changeset 162:c3e8226a5651 heavy-updated

- added additional flags to C rules (-DNDEBUG, -mfpu=neon) - sample-accurate envelope triggering pd/heavy example
author chnrx <chris.heinrichs@gmail.com>
date Thu, 12 Nov 2015 14:59:46 +0000
parents 07735c9d95c8
children 20b52283c7b4
files Makefile projects/heavy/envelopeTrigger/ControlBinop.c projects/heavy/envelopeTrigger/ControlBinop.h projects/heavy/envelopeTrigger/ControlSlice.c projects/heavy/envelopeTrigger/ControlSlice.h projects/heavy/envelopeTrigger/ControlSystem.c projects/heavy/envelopeTrigger/ControlSystem.h projects/heavy/envelopeTrigger/ControlUnop.c projects/heavy/envelopeTrigger/ControlUnop.h projects/heavy/envelopeTrigger/ControlVar.c projects/heavy/envelopeTrigger/ControlVar.h projects/heavy/envelopeTrigger/Heavy.c projects/heavy/envelopeTrigger/HeavyMath.h projects/heavy/envelopeTrigger/Heavy_bbb.h projects/heavy/envelopeTrigger/HvBase.c projects/heavy/envelopeTrigger/HvBase.h projects/heavy/envelopeTrigger/HvContext_bbb.c projects/heavy/envelopeTrigger/HvContext_bbb.h projects/heavy/envelopeTrigger/HvMessage.c projects/heavy/envelopeTrigger/HvMessage.h projects/heavy/envelopeTrigger/HvTable.c projects/heavy/envelopeTrigger/HvTable.h projects/heavy/envelopeTrigger/MessagePool.c projects/heavy/envelopeTrigger/MessagePool.h projects/heavy/envelopeTrigger/MessageQueue.c projects/heavy/envelopeTrigger/MessageQueue.h projects/heavy/envelopeTrigger/SignalBiquad.c projects/heavy/envelopeTrigger/SignalBiquad.h projects/heavy/envelopeTrigger/SignalDel1.c projects/heavy/envelopeTrigger/SignalDel1.h projects/heavy/envelopeTrigger/SignalPhasor.c projects/heavy/envelopeTrigger/SignalPhasor.h projects/heavy/envelopeTrigger/SignalRPole.c projects/heavy/envelopeTrigger/SignalRPole.h projects/heavy/envelopeTrigger/SignalTabread.c projects/heavy/envelopeTrigger/SignalTabread.h projects/heavy/envelopeTrigger/SignalVar.c projects/heavy/envelopeTrigger/SignalVar.h projects/heavy/envelopeTrigger/Utils.h projects/heavy/envelopeTrigger/Utils_mac.c projects/heavy/envelopeTrigger/Utils_mac.h projects/heavy/envelopeTrigger/Utils_unix.c projects/heavy/envelopeTrigger/Utils_unix.h projects/heavy/envelopeTrigger/Utils_windows.c projects/heavy/envelopeTrigger/Utils_windows.h projects/heavy/envelopeTrigger/render.cpp projects/heavy/hello-world/HvContext_bbb.c projects/heavy/hello-world/HvContext_bbb.h projects/heavy/pd/envelopeTrigger/_main.pd projects/heavy/samphold/HvContext_bbb.c projects/heavy/samphold/HvContext_bbb.h scripts/build_pd.sh
diffstat 52 files changed, 6380 insertions(+), 115 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile	Thu Nov 05 19:27:44 2015 +0000
+++ b/Makefile	Thu Nov 12 14:59:46 2015 +0000
@@ -87,7 +87,7 @@
 build/source/%.o: ./source/%.c
 	@echo 'Building file: $<'
 	@echo 'Invoking: GCC C Compiler'
-	gcc $(SYNTAX_FLAG) -I./include $(INCLUDES) -O2 -Wall -c -fmessage-length=0 -U_FORTIFY_SOURCE -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -o "$@" "$<" -std=c99
+	gcc $(SYNTAX_FLAG) -I./include $(INCLUDES) -O2 -Wall -c -fmessage-length=0 -U_FORTIFY_SOURCE -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -o "$@" "$<" -std=c99 -mfpu=neon -DNDEBUG
 	@echo 'Finished building: $<'
 	@echo ' '
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/projects/heavy/envelopeTrigger/ControlBinop.c	Thu Nov 12 14:59:46 2015 +0000
@@ -0,0 +1,94 @@
+/**
+ * Copyright (c) 2014, 2015, Enzien Audio Ltd.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "ControlBinop.h"
+
+hv_size_t cBinop_init(ControlBinop *o, float k) {
+  o->k = k;
+  return 0;
+}
+
+static float cBinop_perform_op(BinopType op, float f, const float k) {
+  switch (op) {
+    case HV_BINOP_ADD: return f + k;
+    case HV_BINOP_SUBTRACT: return f - k;
+    case HV_BINOP_MULTIPLY: return f * k;
+    case HV_BINOP_DIVIDE: return (k != 0.0f) ? f / k : 0.0f;
+    case HV_BINOP_INT_DIV: return (float) ((int) f / (int) k);
+    case HV_BINOP_MOD_BIPOLAR: return (float) ((int) f % (int) k);
+    case HV_BINOP_MOD_UNIPOLAR: {
+      f = (k == 0.0f) ? 0.0f : (float) ((int) f % (int) k);
+      return (f < 0.0f) ? f + fabsf(k) : f;
+    }
+    case HV_BINOP_BIT_LEFTSHIFT: return (float) (((int) f) << ((int) k));
+    case HV_BINOP_BIT_RIGHTSHIFT: return (float) (((int) f) >> ((int) k));
+    case HV_BINOP_BIT_AND: return (float) ((int) f & (int) k);
+    case HV_BINOP_BIT_XOR: return (float) ((int) f ^ (int) k);
+    case HV_BINOP_BIT_OR: return (float) ((int) f | (int) k);
+    case HV_BINOP_EQ: return (f == k) ? 1.0f : 0.0f;
+    case HV_BINOP_NEQ: return (f != k) ? 1.0f : 0.0f;
+    case HV_BINOP_LOGICAL_AND: return ((f == 0.0f) || (k == 0.0f)) ? 0.0f : 1.0f;
+    case HV_BINOP_LOGICAL_OR: return ((f == 0.0f) && (k == 0.0f)) ? 0.0f : 1.0f;
+    case HV_BINOP_LESS_THAN: return (f < k) ? 1.0f : 0.0f;
+    case HV_BINOP_LESS_THAN_EQL: return (f <= k) ? 1.0f : 0.0f;
+    case HV_BINOP_GREATER_THAN: return (f > k) ? 1.0f : 0.0f;
+    case HV_BINOP_GREATER_THAN_EQL: return (f >= k) ? 1.0f : 0.0f;
+    case HV_BINOP_MAX: return hv_max_f(f, k);
+    case HV_BINOP_MIN: return hv_min_f(f, k);
+    case HV_BINOP_POW: return (f > 0.0f) ? powf(f, k) : 0.0f;
+    case HV_BINOP_ATAN2: return ((f == 0.0f) && (k == 0.0f)) ? 0.0f : atan2f(f, k);
+    default: return 0.0f;
+  }
+}
+
+void cBinop_onMessage(HvBase *_c, ControlBinop *o, BinopType op, int letIn,
+    const HvMessage *const m,
+    void (*sendMessage)(HvBase *, int, const HvMessage *const)) {
+  switch (letIn) {
+    case 0: {
+      if (msg_isFloat(m, 0)) {
+        // Note(joe): supporting Pd's ability to perform operations of packs
+        // of floats is likely to not be supported in the future.
+        if (msg_isFloat(m, 1)) o->k = msg_getFloat(m, 1);
+        HvMessage *n = HV_MESSAGE_ON_STACK(1);
+        float f = cBinop_perform_op(op, msg_getFloat(m, 0), o->k);
+        msg_initWithFloat(n, msg_getTimestamp(m), f);
+        sendMessage(_c, 0, n);
+      }
+      break;
+    }
+    case 1: {
+      if (msg_isFloat(m, 0)) {
+        o->k = msg_getFloat(m, 0);
+      }
+      break;
+    }
+    default: break;
+  }
+}
+
+void cBinop_k_onMessage(HvBase *_c, void *o, BinopType op, const float k,
+    int letIn, const HvMessage *const m,
+    void (*sendMessage)(HvBase *, int, const HvMessage *const)) {
+  if (msg_isFloat(m, 0)) {
+    // NOTE(mhroth): Heavy does not support sending bangs to binop objects to return the previous output
+    float f = (msg_isFloat(m, 1)) ? msg_getFloat(m, 1) : k;
+    HvMessage *n = HV_MESSAGE_ON_STACK(1);
+    f = cBinop_perform_op(op, msg_getFloat(m, 0), f);
+    msg_initWithFloat(n, msg_getTimestamp(m), f);
+    sendMessage(_c, 0, n);
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/projects/heavy/envelopeTrigger/ControlBinop.h	Thu Nov 12 14:59:46 2015 +0000
@@ -0,0 +1,63 @@
+/**
+ * Copyright (c) 2014, 2015, Enzien Audio Ltd.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _HEAVY_CONTROL_BINOP_H_
+#define _HEAVY_CONTROL_BINOP_H_
+
+#include "HvBase.h"
+
+typedef enum BinopType {
+  HV_BINOP_ADD,
+  HV_BINOP_SUBTRACT,
+  HV_BINOP_MULTIPLY,
+  HV_BINOP_DIVIDE,
+  HV_BINOP_INT_DIV,
+  HV_BINOP_MOD_BIPOLAR,
+  HV_BINOP_MOD_UNIPOLAR,
+  HV_BINOP_BIT_LEFTSHIFT,
+  HV_BINOP_BIT_RIGHTSHIFT,
+  HV_BINOP_BIT_AND,
+  HV_BINOP_BIT_XOR,
+  HV_BINOP_BIT_OR,
+  HV_BINOP_EQ,
+  HV_BINOP_NEQ,
+  HV_BINOP_LOGICAL_AND,
+  HV_BINOP_LOGICAL_OR,
+  HV_BINOP_LESS_THAN,
+  HV_BINOP_LESS_THAN_EQL,
+  HV_BINOP_GREATER_THAN,
+  HV_BINOP_GREATER_THAN_EQL,
+  HV_BINOP_MAX,
+  HV_BINOP_MIN,
+  HV_BINOP_POW,
+  HV_BINOP_ATAN2
+} BinopType;
+
+typedef struct ControlBinop {
+  float k;
+} ControlBinop;
+
+hv_size_t cBinop_init(ControlBinop *o, float k);
+
+void cBinop_onMessage(HvBase *_c, ControlBinop *o, BinopType op, int letIn,
+    const HvMessage *const m,
+    void (*sendMessage)(HvBase *, int, const HvMessage *const));
+
+void cBinop_k_onMessage(HvBase *_c, void *o, BinopType op, const float k,
+    int letIn, const HvMessage *const m,
+    void (*sendMessage)(HvBase *, int, const HvMessage *const));
+
+#endif // _HEAVY_CONTROL_BINOP_H_
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/projects/heavy/envelopeTrigger/ControlSlice.c	Thu Nov 12 14:59:46 2015 +0000
@@ -0,0 +1,62 @@
+/**
+ * Copyright (c) 2014, 2015, Enzien Audio Ltd.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "ControlSlice.h"
+
+hv_size_t cSlice_init(ControlSlice *o, int i, int n) {
+  o->i = i;
+  o->n = n;
+  return 0;
+}
+
+void cSlice_onMessage(HvBase *_c, ControlSlice *o, int letIn, const HvMessage *const m,
+    void (*sendMessage)(HvBase *, int, const HvMessage *const)) {
+  switch (letIn) {
+    case 0: {
+      // if the start point is greater than the number of elements in the source message, do nothing
+      if (o->i < msg_getNumElements(m)) {
+        int x = msg_getNumElements(m) - o->i; // number of elements in the new message
+        if (o->n > 0) x = hv_min_i(x, o->n);
+        HvMessage *n = HV_MESSAGE_ON_STACK(x);
+        msg_init(n, x, msg_getTimestamp(m));
+        hv_memcpy(&n->elem, &m->elem+o->i, x*sizeof(Element));
+        sendMessage(_c, 0, n);
+      } else {
+        // if nothing can be sliced, send a bang out of the right outlet
+        HvMessage *n = HV_MESSAGE_ON_STACK(1);
+        msg_initWithBang(n, msg_getTimestamp(m));
+        sendMessage(_c, 1, n);
+      }
+      break;
+    }
+    case 1: {
+      if (msg_isFloat(m,0)) {
+        o->i = (int) msg_getFloat(m,0);
+        if (msg_isFloat(m,1)) {
+          o->n = (int) msg_getFloat(m,1);
+        }
+      }
+      break;
+    }
+    case 2: {
+      if (msg_isFloat(m,0)) {
+        o->n = (int) msg_getFloat(m,0);
+      }
+      break;
+    }
+    default: break;
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/projects/heavy/envelopeTrigger/ControlSlice.h	Thu Nov 12 14:59:46 2015 +0000
@@ -0,0 +1,32 @@
+/**
+ * Copyright (c) 2014, 2015, Enzien Audio Ltd.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _HEAVY_CONTROL_SLICE_H_
+#define _HEAVY_CONTROL_SLICE_H_
+
+#include "HvBase.h"
+
+typedef struct ControlSlice {
+  int i; // start index
+  int n; // length of slice
+} ControlSlice;
+
+hv_size_t cSlice_init(ControlSlice *o, int i, int n);
+
+void cSlice_onMessage(HvBase *_c, ControlSlice *o, int letIn, const HvMessage *const m,
+    void (*sendMessage)(HvBase *, int, const HvMessage *const));
+
+#endif // _HEAVY_CONTROL_SLICE_H_
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/projects/heavy/envelopeTrigger/ControlSystem.c	Thu Nov 12 14:59:46 2015 +0000
@@ -0,0 +1,46 @@
+/**
+ * Copyright (c) 2014, 2015, Enzien Audio Ltd.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "ControlSystem.h"
+#include "HvTable.h"
+
+void cSystem_onMessage(HvBase *_c, void *o, int letIn, const HvMessage *const m,
+    void (*sendMessage)(HvBase *, int, const HvMessage *const)) {
+
+  HvMessage *n = HV_MESSAGE_ON_STACK(1);
+  if (msg_compareSymbol(m, 0, "samplerate")) {
+    msg_initWithFloat(n, msg_getTimestamp(m), (float) ctx_getSampleRate(_c));
+  } else if (msg_compareSymbol(m, 0, "numInputChannels")) {
+    msg_initWithFloat(n, msg_getTimestamp(m), (float) ctx_getNumInputChannels(_c));
+  } else if (msg_compareSymbol(m, 0, "numOutputChannels")) {
+    msg_initWithFloat(n, msg_getTimestamp(m), (float) ctx_getNumOutputChannels(_c));
+  } else if (msg_compareSymbol(m, 0, "currentTime")) {
+    msg_initWithFloat(n, msg_getTimestamp(m), (float) msg_getTimestamp(m));
+  } else if (msg_compareSymbol(m, 0, "table")) {
+    // NOTE(mhroth): no need to check message format for symbols as table lookup will fail otherwise
+    HvTable *o = ctx_getTableForHash(_c, msg_getHash(m,1));
+    if (o != NULL) {
+      if (msg_compareSymbol(m, 2, "length")) {
+        msg_initWithFloat(n, msg_getTimestamp(m), (float) hTable_getLength(o));
+      } else if (msg_compareSymbol(m, 2, "size")) {
+        msg_initWithFloat(n, msg_getTimestamp(m), (float) hTable_getSize(o));
+      } else if (msg_compareSymbol(m, 2, "head")) {
+        msg_initWithFloat(n, msg_getTimestamp(m), (float) hTable_getHead(o));
+      } else return;
+    } else return;
+  } else return;
+  sendMessage(_c, 0, n);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/projects/heavy/envelopeTrigger/ControlSystem.h	Thu Nov 12 14:59:46 2015 +0000
@@ -0,0 +1,25 @@
+/**
+ * Copyright (c) 2014, 2015, Enzien Audio Ltd.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _HEAVY_CONTROL_SYSTEM_H_
+#define _HEAVY_CONTROL_SYSTEM_H_
+
+#include "HvBase.h"
+
+void cSystem_onMessage(HvBase *_c, void *o, int letIn, const HvMessage *const m,
+    void (*sendMessage)(HvBase *, int, const HvMessage *const));
+
+#endif // _HEAVY_CONTROL_SYSTEM_H_
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/projects/heavy/envelopeTrigger/ControlUnop.c	Thu Nov 12 14:59:46 2015 +0000
@@ -0,0 +1,52 @@
+/**
+ * Copyright (c) 2014, 2015, Enzien Audio Ltd.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "ControlUnop.h"
+#include "HvBase.h"
+
+void cUnop_onMessage(HvBase *_c, UnopType op, const HvMessage *const m,
+    void (*sendMessage)(HvBase *, int, const HvMessage *const )) {
+  if (msg_isFloat(m, 0)) {
+    float f = msg_getFloat(m, 0);
+    switch (op) {
+      case HV_UNOP_SIN: f = hv_sin_f(f); break;
+      case HV_UNOP_SINH: f = hv_sinh_f(f); break;
+      case HV_UNOP_COS: f = hv_cos_f(f); break;
+      case HV_UNOP_COSH: f = hv_cosh_f(f); break;
+      case HV_UNOP_TAN: f = hv_tan_f(f); break;
+      case HV_UNOP_TANH: f = hv_tanh_f(f); break;
+      case HV_UNOP_ASIN: f = hv_asin_f(f); break;
+      case HV_UNOP_ASINH: f = hv_asinh_f(f); break;
+      case HV_UNOP_ACOS: f = hv_acos_f(f); break;
+      case HV_UNOP_ACOSH: f = hv_acosh_f(f); break;
+      case HV_UNOP_ATAN: f = hv_atan_f(f); break;
+      case HV_UNOP_ATANH: f = hv_atanh_f(f); break;
+      case HV_UNOP_EXP: f = hv_exp_f(f); break;
+      case HV_UNOP_ABS: f = hv_abs_f(f); break;
+      case HV_UNOP_SQRT: f = (f > 0.0f) ? hv_sqrt_f(f) : 0.0f; break;
+      case HV_UNOP_LOG: f = (f > 0.0f) ? hv_log_f(f) : 0.0f; break;
+      case HV_UNOP_LOG2: f = (f > 0.0f) ? hv_log2_f(f) : 0.0f; break;
+      case HV_UNOP_LOG10: f = (f > 0.0f) ? hv_log10_f(f) : 0.0f; break;
+      case HV_UNOP_CEIL: f = hv_ceil_f(f); break;
+      case HV_UNOP_FLOOR: f = hv_floor_f(f); break;
+      case HV_UNOP_ROUND: f = hv_round_f(f); break;
+      default: return;
+    }
+    HvMessage *n = HV_MESSAGE_ON_STACK(1);
+    msg_initWithFloat(n, m->timestamp, f);
+    sendMessage(_c, 0, n);
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/projects/heavy/envelopeTrigger/ControlUnop.h	Thu Nov 12 14:59:46 2015 +0000
@@ -0,0 +1,50 @@
+/**
+ * Copyright (c) 2014, 2015, Enzien Audio Ltd.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _HEAVY_CONTROL_UNOP_H_
+#define _HEAVY_CONTROL_UNOP_H_
+
+struct HvBase;
+struct HvMessage;
+
+typedef enum UnopType {
+  HV_UNOP_ASIN,
+  HV_UNOP_ASINH,
+  HV_UNOP_ACOS,
+  HV_UNOP_ACOSH,
+  HV_UNOP_ATAN,
+  HV_UNOP_ATANH,
+  HV_UNOP_SIN,
+  HV_UNOP_SINH,
+  HV_UNOP_COS,
+  HV_UNOP_COSH,
+  HV_UNOP_TAN,
+  HV_UNOP_TANH,
+  HV_UNOP_EXP,
+  HV_UNOP_ABS,
+  HV_UNOP_SQRT,
+  HV_UNOP_LOG,
+  HV_UNOP_LOG2,
+  HV_UNOP_LOG10,
+  HV_UNOP_CEIL,
+  HV_UNOP_FLOOR,
+  HV_UNOP_ROUND
+} UnopType;
+
+void cUnop_onMessage(struct HvBase *_c, UnopType op, const struct HvMessage *const m,
+    void (*sendMessage)(struct HvBase *, int, const struct HvMessage *const));
+
+#endif // _HEAVY_CONTROL_UNOP_H_
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/projects/heavy/envelopeTrigger/ControlVar.c	Thu Nov 12 14:59:46 2015 +0000
@@ -0,0 +1,83 @@
+/**
+ * Copyright (c) 2014, 2015, Enzien Audio Ltd.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "ControlVar.h"
+
+hv_size_t cVar_init_f(ControlVar *o, float k) {
+  o->e.type = FLOAT;
+  o->e.data.f = k;
+  return 0;
+}
+
+hv_size_t cVar_init_s(ControlVar *o, const char *s) {
+  o->e.type = HASH;
+  o->e.data.h = msg_symbolToHash(s);
+  return 0;
+}
+
+void cVar_free(ControlVar *o) {
+  // nothing to do
+}
+
+void cVar_onMessage(HvBase *_c, ControlVar *o, int letIn, const HvMessage *const m,
+    void (*sendMessage)(HvBase *, int, const HvMessage *const)) {
+  switch (letIn) {
+    case 0: {
+      switch (msg_getType(m,0)) {
+        case BANG: {
+          HvMessage *n = HV_MESSAGE_ON_STACK(1);
+          if (o->e.type == FLOAT) msg_initWithFloat(n, msg_getTimestamp(m), o->e.data.f);
+          else if (o->e.type == HASH) msg_initWithHash(n, msg_getTimestamp(m), o->e.data.h);
+          else return;
+          sendMessage(_c, 0, n);
+          break;
+        }
+        case FLOAT: {
+          o->e.type = FLOAT;
+          o->e.data.f = msg_getFloat(m,0);
+          sendMessage(_c, 0, m);
+          break;
+        }
+        case SYMBOL:
+        case HASH: {
+          o->e.type = HASH;
+          o->e.data.h = msg_getHash(m,0);
+          sendMessage(_c, 0, m);
+          break;
+        }
+        default: return;
+      }
+      break;
+    }
+    case 1: {
+      switch (msg_getType(m,0)) {
+        case FLOAT: {
+          o->e.type = FLOAT;
+          o->e.data.f = msg_getFloat(m,0);
+          break;
+        }
+        case SYMBOL:
+        case HASH: {
+          o->e.type = HASH;
+          o->e.data.h = msg_getHash(m,0);
+          break;
+        }
+        default: break;
+      }
+    }
+    default: return;
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/projects/heavy/envelopeTrigger/ControlVar.h	Thu Nov 12 14:59:46 2015 +0000
@@ -0,0 +1,35 @@
+/**
+ * Copyright (c) 2014, 2015, Enzien Audio Ltd.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _HEAVY_CONTROL_VAR_H_
+#define _HEAVY_CONTROL_VAR_H_
+
+#include "HvBase.h"
+
+typedef struct ControlVar {
+  Element e; // type is only every FLOAT or HASH
+} ControlVar;
+
+hv_size_t cVar_init_f(ControlVar *o, float k);
+
+hv_size_t cVar_init_s(ControlVar *o, const char *s);
+
+void cVar_free(ControlVar *o);
+
+void cVar_onMessage(HvBase *_c, ControlVar *o, int letIn, const HvMessage *const m,
+    void (*sendMessage)(HvBase *, int, const HvMessage *const));
+
+#endif // _HEAVY_CONTROL_VAR_H_
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/projects/heavy/envelopeTrigger/Heavy.c	Thu Nov 12 14:59:46 2015 +0000
@@ -0,0 +1,196 @@
+/**
+ * Copyright (c) 2014, 2015, Enzien Audio Ltd.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "HvBase.h"
+#include "HvTable.h"
+
+#if !HV_WIN
+#pragma mark - Heavy Table
+#endif
+
+int hv_table_resize(HvTable *o, hv_uint32_t newLength) {
+  return hTable_resize(o, newLength);
+}
+
+float *hv_table_getBuffer(HvTable *o) {
+  return hTable_getBuffer(o);
+}
+
+hv_size_t hv_table_getLength(HvTable *o) {
+  return hTable_getLength(o);
+}
+
+
+
+#if !HV_WIN
+#pragma mark - Heavy Message
+#endif
+
+hv_size_t hv_msg_getByteSize (hv_uint32_t numElements) {
+  return msg_getByteSize(numElements);
+}
+
+void hv_msg_init(HvMessage *m, int numElements, hv_uint32_t timestamp) {
+  msg_init(m, numElements, timestamp);
+}
+
+hv_size_t hv_msg_getNumElements(const HvMessage *const m) {
+  return msg_getNumElements(m);
+}
+
+double hv_msg_getTimestamp(const HvMessage *const m) {
+  return msg_getTimestamp(m);
+}
+
+void hv_msg_setTimestamp(HvMessage *m, hv_uint32_t timestamp) {
+  msg_setTimestamp(m, timestamp);
+}
+
+bool hv_msg_isBang(const HvMessage *const m, int i) {
+  return msg_isBang(m,i);
+}
+
+void hv_msg_setBang(HvMessage *m, int i) {
+  msg_setBang(m,i);
+}
+
+bool hv_msg_isFloat(const HvMessage *const m, int i) {
+  return msg_isFloat(m, i);
+}
+
+float hv_msg_getFloat(const HvMessage *const m, int i) {
+  return msg_getFloat(m,i);
+}
+
+void hv_msg_setFloat(HvMessage *m, int i, float f) {
+  msg_setFloat(m,i,f);
+}
+
+bool hv_msg_isSymbol(const HvMessage *const m, int i) {
+  return msg_isSymbol(m,i);
+}
+
+char *hv_msg_getSymbol(const HvMessage *const m, int i) {
+  return msg_getSymbol(m,i);
+}
+
+void hv_msg_setSymbol(HvMessage *m, int i, char *s) {
+  msg_setSymbol(m,i,s);
+}
+
+bool hv_msg_isHash(const HvMessage *const m, int i) {
+  return msg_isHash(m, i);
+}
+
+unsigned int hv_msg_getHash(const HvMessage *const m, int i) {
+  return msg_getHash(m, i);
+}
+
+bool hv_msg_hasFormat(const HvMessage *const m, const char *fmt) {
+  return msg_hasFormat(m, fmt);
+}
+
+char *hv_msg_toString(const HvMessage *const m) {
+  return msg_toString(m);
+}
+
+HvMessage *hv_msg_copy(HvMessage *m) {
+  return msg_copy(m);
+}
+
+void hv_msg_free(HvMessage *m) {
+  msg_free(m);
+}
+
+
+
+#if !HV_WIN
+#pragma mark - Heavy Common
+#endif
+
+double hv_getSampleRate(HvBase *c) {
+  return ctx_getSampleRate(c);
+}
+
+int hv_getNumInputChannels(HvBase *c) {
+  return ctx_getNumInputChannels(c);
+}
+
+int hv_getNumOutputChannels(HvBase *c) {
+  return ctx_getNumOutputChannels(c);
+}
+
+const char *hv_getName(HvBase *c) {
+  return ctx_getName(c);
+}
+
+void hv_setPrintHook(HvBase *c, void (*f)(double, const char *, const char *, void *)) {
+  ctx_setPrintHook(c, f);
+}
+
+void hv_setSendHook(HvBase *c, void (*f)(double, const char *, const HvMessage *const, void *)) {
+  ctx_setSendHook(c, f);
+}
+
+void hv_vscheduleMessageForReceiver(HvBase *c, const char *receiverName, const double delayMs, const char *format, ...) {
+  va_list ap;
+  va_start(ap, format);
+
+  const int numElem = (int) hv_strlen(format);
+  HvMessage *m = HV_MESSAGE_ON_STACK(numElem);
+  msg_init(m, numElem, c->blockStartTimestamp + (hv_uint32_t) (hv_max_d(0.0, delayMs)*ctx_getSampleRate(c)/1000.0));
+  for (int i = 0; i < numElem; i++) {
+    switch (format[i]) {
+      case 'b': msg_setBang(m,i); break;
+      case 'f': msg_setFloat(m, i, (float) va_arg(ap, double)); break;
+      case 's': msg_setSymbol(m, i, (char *) va_arg(ap, char *)); break;
+      default: break;
+    }
+  }
+  ctx_scheduleMessageForReceiver(c, receiverName, m);
+
+  va_end(ap);
+}
+
+void hv_scheduleMessageForReceiver(HvBase *c, const char *receiverName, double delayMs, HvMessage *m) {
+  hv_assert(delayMs >= 0.0);
+  msg_setTimestamp(m, c->blockStartTimestamp + (hv_uint32_t) (delayMs*ctx_getSampleRate(c)/1000.0));
+  ctx_scheduleMessageForReceiver(c, receiverName, m);
+}
+
+HvTable *hv_getTableForName(HvBase *c, const char *tableName) {
+  return ctx_getTableForName(c, tableName);
+}
+
+void hv_cancelMessage(HvBase *c, HvMessage *m) {
+  ctx_cancelMessage(c, m, NULL);
+}
+
+double hv_getCurrentTime(HvBase *c) {
+  return ((double) c->blockStartTimestamp)/c->sampleRate;
+}
+
+void *hv_getUserData(HvBase *c) {
+  return ctx_getUserData(c);
+}
+
+void hv_setUserData(HvBase *c, void *userData) {
+  ctx_setUserData(c, userData);
+}
+
+void hv_setBasePath(HvBase *c, const char *basePath) {
+  ctx_setBasePath(c, basePath);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/projects/heavy/envelopeTrigger/HeavyMath.h	Thu Nov 12 14:59:46 2015 +0000
@@ -0,0 +1,645 @@
+/**
+ * Copyright (c) 2014, 2015, Enzien Audio Ltd.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _HEAVY_MATH_H_
+#define _HEAVY_MATH_H_
+
+#include "Utils.h"
+
+// https://software.intel.com/sites/landingpage/IntrinsicsGuide/
+// https://gcc.gnu.org/onlinedocs/gcc-4.8.1/gcc/ARM-NEON-Intrinsics.html
+// http://codesuppository.blogspot.co.uk/2015/02/sse2neonh-porting-guide-and-header-file.html
+
+static inline void __hv_zero_f(hv_bOutf_t bOut) {
+#if HV_SIMD_AVX
+  *bOut = _mm256_setzero_ps();
+#elif HV_SIMD_SSE
+  *bOut = _mm_setzero_ps();
+#elif HV_SIMD_NEON
+  *bOut = vdupq_n_f32(0.0f);
+#else // HV_SIMD_NONE
+  *bOut = 0.0f;
+#endif
+}
+
+static inline void __hv_load_f(float *bIn, hv_bOutf_t bOut) {
+#if HV_SIMD_AVX
+  *bOut = _mm256_load_ps(bIn);
+#elif HV_SIMD_SSE
+  *bOut = _mm_load_ps(bIn);
+#elif HV_SIMD_NEON
+  *bOut = vld1q_f32(bIn);
+#else // HV_SIMD_NONE
+  *bOut = *bIn;
+#endif
+}
+
+static inline void __hv_store_f(float *bOut, hv_bInf_t bIn) {
+#if HV_SIMD_AVX
+  _mm256_store_ps(bOut, bIn);
+#elif HV_SIMD_SSE
+  _mm_store_ps(bOut, bIn);
+#elif HV_SIMD_NEON
+  vst1q_f32(bOut, bIn);
+#else // HV_SIMD_NONE
+  *bOut = bIn;
+#endif
+}
+
+static inline void __hv_log_f(hv_bInf_t bIn, hv_bOutf_t bOut) {
+#if HV_SIMD_AVX
+#warning __hv_log_f() not implemented
+#elif HV_SIMD_SSE
+#warning __hv_log_f() not implemented
+#elif HV_SIMD_NEON
+#warning __hv_log_f() not implemented
+#else // HV_SIMD_NONE
+  *bOut = (bIn > 0.0f) ? hv_log_f(bIn) : 0.0f;
+#endif
+}
+
+static inline void __hv_log10_f(hv_bInf_t bIn, hv_bOutf_t bOut) {
+#if HV_SIMD_AVX
+#warning __hv_log10_f() not implemented
+#elif HV_SIMD_SSE
+#warning __hv_log10_f() not implemented
+#elif HV_SIMD_NEON
+#warning __hv_log10_f() not implemented
+#else // HV_SIMD_NONE
+  *bOut = (bIn > 0.0f) ? hv_log10_f(bIn) : 0.0f;
+#endif
+}
+
+static inline void __hv_log2_f(hv_bInf_t bIn, hv_bOutf_t bOut) {
+#if HV_SIMD_AVX
+#warning __hv_log2_f() not implemented
+#elif HV_SIMD_SSE
+#warning __hv_log2_f() not implemented
+#elif HV_SIMD_NEON
+#warning __hv_log2_f() not implemented
+#else // HV_SIMD_NONE
+  *bOut = (bIn > 0.0f) ? hv_log2_f(bIn) : 0.0f;
+#endif
+}
+
+// NOTE(mhroth): this is a pretty ghetto implementation
+static inline void __hv_cos_f(hv_bInf_t bIn, hv_bOutf_t bOut) {
+#if HV_SIMD_AVX
+  *bOut = _mm256_set_ps(
+      hv_cos_f(bIn[7]), hv_cos_f(bIn[6]), hv_cos_f(bIn[5]), hv_cos_f(bIn[4]),
+      hv_cos_f(bIn[3]), hv_cos_f(bIn[2]), hv_cos_f(bIn[1]), hv_cos_f(bIn[0]));
+#elif HV_SIMD_SSE
+  *bOut = _mm_set_ps(hv_cos_f(bIn[3]), hv_cos_f(bIn[2]), hv_cos_f(bIn[1]), hv_cos_f(bIn[0]));
+#elif HV_SIMD_NEON
+  *bOut = (float32x4_t) {hv_cos_f(bIn[0]), hv_cos_f(bIn[1]), hv_cos_f(bIn[2]), hv_cos_f(bIn[3])};
+#else // HV_SIMD_NONE
+  *bOut = hv_cos_f(bIn);
+#endif
+}
+
+static inline void __hv_acos_f(hv_bInf_t bIn, hv_bOutf_t bOut) {
+#if HV_SIMD_AVX
+#warning __hv_acos_f() not implemented
+#elif HV_SIMD_SSE
+#warning __hv_acos_f() not implemented
+#elif HV_SIMD_NEON
+#warning __hv_acos_f() not implemented
+#else // HV_SIMD_NONE
+  *bOut = hv_acos_f(bIn);
+#endif
+}
+
+static inline void __hv_cosh_f(hv_bInf_t bIn, hv_bOutf_t bOut) {
+#if HV_SIMD_AVX
+#warning __hv_cosh_f() not implemented
+#elif HV_SIMD_SSE
+#warning __hv_cosh_f() not implemented
+#elif HV_SIMD_NEON
+#warning __hv_cosh_f() not implemented
+#else // HV_SIMD_NONE
+  *bOut = hv_cosh_f(bIn);
+#endif
+}
+
+static inline void __hv_acosh_f(hv_bInf_t bIn, hv_bOutf_t bOut) {
+#if HV_SIMD_AVX
+#warning __hv_acosh_f() not implemented
+#elif HV_SIMD_SSE
+#warning __hv_acosh_f() not implemented
+#elif HV_SIMD_NEON
+#warning __hv_acosh_f() not implemented
+#else // HV_SIMD_NONE
+  *bOut = hv_acosh_f(bIn);
+#endif
+}
+
+static inline void __hv_sin_f(hv_bInf_t bIn, hv_bOutf_t bOut) {
+#if HV_SIMD_AVX
+#warning __hv_sin_f() not implemented
+#elif HV_SIMD_SSE
+#warning __hv_sin_f() not implemented
+#elif HV_SIMD_NEON
+#warning __hv_sin_f() not implemented
+#else // HV_SIMD_NONE
+  *bOut = hv_sin_f(bIn);
+#endif
+}
+
+static inline void __hv_asin_f(hv_bInf_t bIn, hv_bOutf_t bOut) {
+#if HV_SIMD_AVX
+#warning __hv_asin_f() not implemented
+#elif HV_SIMD_SSE
+#warning __hv_asin_f() not implemented
+#elif HV_SIMD_NEON
+#warning __hv_asin_f() not implemented
+#else // HV_SIMD_NONE
+  *bOut = hv_asin_f(bIn);
+#endif
+}
+
+static inline void __hv_sinh_f(hv_bInf_t bIn, hv_bOutf_t bOut) {
+#if HV_SIMD_AVX
+#warning __hv_sinh_f() not implemented
+#elif HV_SIMD_SSE
+#warning __hv_sinh_f() not implemented
+#elif HV_SIMD_NEON
+#warning __hv_sinh_f() not implemented
+#else // HV_SIMD_NONE
+  *bOut = hv_sinh_f(bIn);
+#endif
+}
+
+static inline void __hv_asinh_f(hv_bInf_t bIn, hv_bOutf_t bOut) {
+#if HV_SIMD_AVX
+#warning __hv_asinh_f() not implemented
+#elif HV_SIMD_SSE
+#warning __hv_asinh_f() not implemented
+#elif HV_SIMD_NEON
+#warning __hv_asinh_f() not implemented
+#else // HV_SIMD_NONE
+  *bOut = hv_asinh_f(bIn);
+#endif
+}
+
+static inline void __hv_tan_f(hv_bInf_t bIn, hv_bOutf_t bOut) {
+#if HV_SIMD_AVX
+#warning __hv_tan_f() not implemented
+#elif HV_SIMD_SSE
+#warning __hv_tan_f() not implemented
+#elif HV_SIMD_NEON
+#warning __hv_tan_f() not implemented
+#else // HV_SIMD_NONE
+  *bOut = hv_tan_f(bIn);
+#endif
+}
+
+static inline void __hv_atan_f(hv_bInf_t bIn, hv_bOutf_t bOut) {
+#if HV_SIMD_AVX
+#warning __hv_atan_f() not implemented
+#elif HV_SIMD_SSE
+#warning __hv_atan_f() not implemented
+#elif HV_SIMD_NEON
+#warning __hv_atan_f() not implemented
+#else // HV_SIMD_NONE
+  *bOut = hv_atan_f(bIn);
+#endif
+}
+
+static inline void __hv_atan2_f(hv_bInf_t bIn0, hv_bInf_t bIn1, hv_bOutf_t bOut) {
+#if HV_SIMD_AVX
+#warning __hv_atan2_f() not implemented
+#elif HV_SIMD_SSE
+#warning __hv_atan2_f() not implemented
+#elif HV_SIMD_NEON
+#warning __hv_atan2_f() not implemented
+#else // HV_SIMD_NONE
+  *bOut = hv_atan2_f(bIn0, bIn1);
+#endif
+}
+
+static inline void __hv_tanh_f(hv_bInf_t bIn, hv_bOutf_t bOut) {
+#if HV_SIMD_AVX
+#warning __hv_tanh_f() not implemented
+#elif HV_SIMD_SSE
+#warning __hv_tanh_f() not implemented
+#elif HV_SIMD_NEON
+#warning __hv_tanh_f() not implemented
+#else // HV_SIMD_NONE
+  *bOut = hv_tanh_f(bIn);
+#endif
+}
+
+static inline void __hv_atanh_f(hv_bInf_t bIn, hv_bOutf_t bOut) {
+#if HV_SIMD_AVX
+#warning __hv_atanh_f() not implemented
+#elif HV_SIMD_SSE
+#warning __hv_atanh_f() not implemented
+#elif HV_SIMD_NEON
+#warning __hv_atanh_f() not implemented
+#else // HV_SIMD_NONE
+  *bOut = hv_atanh_f(bIn);
+#endif
+}
+
+// NOTE(mhroth): use of sqrt is absolute and total MURDER. Make do with recipocal sqrt if possible!!
+static inline void __hv_sqrt_f(hv_bInf_t bIn, hv_bOutf_t bOut) {
+#if HV_SIMD_AVX
+  *bOut = _mm256_sqrt_ps(bIn);
+#elif HV_SIMD_SSE
+  *bOut = _mm_sqrt_ps(bIn);
+#elif HV_SIMD_NEON
+#warning __hv_sqrt_f() numerical results may be inexact
+  *bOut = vrecpeq_f32(vrsqrteq_f32(bIn));
+#else // HV_SIMD_NONE
+  *bOut = hv_sqrt_f(bIn);
+#endif
+}
+
+static inline void __hv_rsqrt_f(hv_bInf_t bIn, hv_bOutf_t bOut) {
+#if HV_SIMD_AVX
+  *bOut = _mm256_rsqrt_ps(bIn);
+#elif HV_SIMD_SSE
+  *bOut = _mm_rsqrt_ps(bIn);
+#elif HV_SIMD_NEON
+#warning __hv_rsqrt_f() numerical results may be inexact
+  *bOut = vrsqrteq_f32(bIn);
+#else // HV_SIMD_NONE
+  *bOut = 1.0f/hv_sqrt_f(bIn);
+#endif
+}
+
+static inline void __hv_abs_f(hv_bInf_t bIn, hv_bOutf_t bOut) {
+#if HV_SIMD_AVX
+  *bOut = _mm256_andnot_ps(_mm256_set1_ps(-0.0f), bIn);
+#elif HV_SIMD_SSE
+  *bOut = _mm_andnot_ps(_mm_set1_ps(-0.0f), bIn); // == 1 << 31
+#elif HV_SIMD_NEON
+  *bOut = vabsq_f32(bIn);
+#else // HV_SIMD_NONE
+  *bOut = hv_abs_f(bIn);
+#endif
+}
+
+static inline void __hv_exp_f(hv_bInf_t bIn, hv_bOutf_t bOut) {
+#if HV_SIMD_AVX
+#warning __hv_exp_f() not implemented
+#elif HV_SIMD_SSE
+#warning __hv_exp_f() not implemented
+#elif HV_SIMD_NEON
+#warning __hv_exp_f() not implemented
+#else // HV_SIMD_NONE
+  *bOut = hv_exp_f(bIn);
+#endif
+}
+
+static inline void __hv_ceil_f(hv_bInf_t bIn, hv_bOutf_t bOut) {
+#if HV_SIMD_AVX
+  *bOut = _mm256_ceil_ps(bIn);
+#elif HV_SIMD_SSE
+  *bOut = _mm_ceil_ps(bIn);
+#elif HV_SIMD_NEON
+#if __ARM_ARCH >= 8
+  *bOut = vrndpq_f32(bIn);
+#else
+#warning A slow NEON implementation of __hv_ceil_f() is being used because the necessary intrinsic cannot be found. It is only available in ARMv8.
+  *bOut = (float32x4_t) {hv_ceil_f(bIn[0]), hv_ceil_f(bIn[1]), hv_ceil_f(bIn[2]), hv_ceil_f(bIn[3])};
+#endif // vrndpq_f32
+#else // HV_SIMD_NONE
+  *bOut = hv_ceil_f(bIn);
+#endif
+}
+
+static inline void __hv_floor_f(hv_bInf_t bIn, hv_bOutf_t bOut) {
+#if HV_SIMD_AVX
+  *bOut = _mm256_floor_ps(bIn);
+#elif HV_SIMD_SSE
+  *bOut = _mm_floor_ps(bIn);
+#elif HV_SIMD_NEON
+#if __ARM_ARCH >= 8
+  *bOut = vrndmq_f32(bIn);
+#else
+#warning A slow NEON implementation of __hv_floor_f() is being used because the necessary intrinsic cannot be found. It is only available in ARMv8.
+  *bOut = (float32x4_t) {hv_floor_f(bIn[0]), hv_floor_f(bIn[1]), hv_floor_f(bIn[2]), hv_floor_f(bIn[3])};
+#endif // vrndmq_f32
+#else // HV_SIMD_NONE
+  *bOut = hv_floor_f(bIn);
+#endif
+}
+
+// __add~f
+static inline void __hv_add_f(hv_bInf_t bIn0, hv_bInf_t bIn1, hv_bOutf_t bOut) {
+#if HV_SIMD_AVX
+  *bOut = _mm256_add_ps(bIn0, bIn1);
+#elif HV_SIMD_SSE
+  *bOut = _mm_add_ps(bIn0, bIn1);
+#elif HV_SIMD_NEON
+  *bOut = vaddq_f32(bIn0, bIn1);
+#else // HV_SIMD_NONE
+  *bOut = bIn0 + bIn1;
+#endif
+}
+
+// __add~i
+static inline void __hv_add_i(hv_bIni_t bIn0, hv_bIni_t bIn1, hv_bOuti_t bOut) {
+#if HV_SIMD_AVX
+  __m128i x = _mm_add_epi32(_mm256_castsi256_si128(bIn0), _mm256_castsi256_si128(bIn1));
+  __m128i y = _mm_add_epi32(_mm256_extractf128_si256(bIn0, 1), _mm256_extractf128_si256(bIn1, 1));
+  *bOut = _mm256_insertf128_si256(_mm256_castsi128_si256(x), y, 1);
+#elif HV_SIMD_SSE
+  *bOut = _mm_add_epi32(bIn0, bIn1);
+#elif HV_SIMD_NEON
+  *bOut = vaddq_s32(bIn0, bIn1);
+#else // HV_SIMD_NONE
+  *bOut = bIn0 + bIn1;
+#endif
+}
+
+// __sub~f
+static inline void __hv_sub_f(hv_bInf_t bIn0, hv_bInf_t bIn1, hv_bOutf_t bOut) {
+#if HV_SIMD_AVX
+  *bOut = _mm256_sub_ps(bIn0, bIn1);
+#elif HV_SIMD_SSE
+  *bOut = _mm_sub_ps(bIn0, bIn1);
+#elif HV_SIMD_NEON
+  *bOut = vsubq_f32(bIn0, bIn1);
+#else // HV_SIMD_NONE
+  *bOut = bIn0 - bIn1;
+#endif
+}
+
+// __mul~f
+static inline void __hv_mul_f(hv_bInf_t bIn0, hv_bInf_t bIn1, hv_bOutf_t bOut) {
+#if HV_SIMD_AVX
+  *bOut = _mm256_mul_ps(bIn0, bIn1);
+#elif HV_SIMD_SSE
+  *bOut = _mm_mul_ps(bIn0, bIn1);
+#elif HV_SIMD_NEON
+  *bOut = vmulq_f32(bIn0, bIn1);
+#else // HV_SIMD_NONE
+  *bOut = bIn0 * bIn1;
+#endif
+}
+
+// __*~i
+static inline void __hv_mul_i(hv_bIni_t bIn0, hv_bIni_t bIn1, hv_bOuti_t bOut) {
+#if HV_SIMD_AVX
+  __m128i x = _mm_mullo_epi32(_mm256_castsi256_si128(bIn0), _mm256_castsi256_si128(bIn1));
+  __m128i y = _mm_mullo_epi32(_mm256_extractf128_si256(bIn0, 1), _mm256_extractf128_si256(bIn1, 1));
+  *bOut = _mm256_insertf128_si256(_mm256_castsi128_si256(x), y, 1);
+#elif HV_SIMD_SSE
+  *bOut = _mm_mullo_epi32(bIn0, bIn1);
+#elif HV_SIMD_NEON
+  *bOut = vmulq_s32(bIn0, bIn1);
+#else // HV_SIMD_NONE
+  *bOut = bIn0 * bIn1;
+#endif
+}
+
+// __cast~if
+static inline void __hv_cast_if(hv_bIni_t bIn, hv_bOutf_t bOut) {
+#if HV_SIMD_AVX
+  *bOut = _mm256_cvtepi32_ps(bIn);
+#elif HV_SIMD_SSE
+  *bOut = _mm_cvtepi32_ps(bIn);
+#elif HV_SIMD_NEON
+  *bOut = vcvtq_f32_s32(bIn);
+#else // HV_SIMD_NONE
+  *bOut = (float) bIn;
+#endif
+}
+
+// __cast~fi
+static inline void __hv_cast_fi(hv_bInf_t bIn, hv_bOuti_t bOut) {
+#if HV_SIMD_AVX
+  *bOut = _mm256_cvtps_epi32(bIn);
+#elif HV_SIMD_SSE
+  *bOut = _mm_cvtps_epi32(bIn);
+#elif HV_SIMD_NEON
+  *bOut = vcvtq_s32_f32(bIn);
+#else // HV_SIMD_NONE
+  *bOut = (int) bIn;
+#endif
+}
+
+static inline void __hv_div_f(hv_bInf_t bIn0, hv_bInf_t bIn1, hv_bOutf_t bOut) {
+#if HV_SIMD_AVX
+  *bOut = _mm256_div_ps(bIn0, bIn1);
+#elif HV_SIMD_SSE
+  *bOut = _mm_div_ps(bIn0, bIn1);
+#elif HV_SIMD_NEON
+#warning __hv_div_f() numerical results may be inexact
+  *bOut = vmulq_f32(bIn0, vrecpeq_f32(bIn1));
+#else // HV_SIMD_NONE
+  *bOut = (bIn1 != 0.0f) ? (bIn0 / bIn1) : 0.0f;
+#endif
+}
+
+static inline void __hv_min_f(hv_bInf_t bIn0, hv_bInf_t bIn1, hv_bOutf_t bOut) {
+#if HV_SIMD_AVX
+  *bOut = _mm256_min_ps(bIn0, bIn1);
+#elif HV_SIMD_SSE
+  *bOut = _mm_min_ps(bIn0, bIn1);
+#elif HV_SIMD_NEON
+  *bOut = vminq_f32(bIn0, bIn1);
+#else // HV_SIMD_NONE
+  *bOut = hv_min_f(bIn0, bIn1);
+#endif
+}
+
+static inline void __hv_min_i(hv_bIni_t bIn0, hv_bIni_t bIn1, hv_bOuti_t bOut) {
+#if HV_SIMD_AVX
+  __m128i x = _mm_min_epi32(_mm256_castsi256_si128(bIn0), _mm256_castsi256_si128(bIn1));
+  __m128i y = _mm_min_epi32(_mm256_extractf128_si256(bIn0, 1), _mm256_extractf128_si256(bIn1, 1));
+  *bOut = _mm256_insertf128_si256(_mm256_castsi128_si256(x), y, 1);
+#elif HV_SIMD_SSE
+  *bOut = _mm_min_epi32(bIn0, bIn1);
+#elif HV_SIMD_NEON
+  *bOut = vminq_s32(bIn0, bIn1);
+#else // HV_SIMD_NONE
+  *bOut = hv_min_i(bIn0, bIn1);
+#endif
+}
+
+static inline void __hv_max_f(hv_bInf_t bIn0, hv_bInf_t bIn1, hv_bOutf_t bOut) {
+#if HV_SIMD_AVX
+  *bOut = _mm256_max_ps(bIn0, bIn1);
+#elif HV_SIMD_SSE
+  *bOut = _mm_max_ps(bIn0, bIn1);
+#elif HV_SIMD_NEON
+  *bOut = vmaxq_f32(bIn0, bIn1);
+#else // HV_SIMD_NONE
+  *bOut = hv_max_f(bIn0, bIn1);
+#endif
+}
+
+static inline void __hv_max_i(hv_bIni_t bIn0, hv_bIni_t bIn1, hv_bOuti_t bOut) {
+#if HV_SIMD_AVX
+  __m128i x = _mm_max_epi32(_mm256_castsi256_si128(bIn0), _mm256_castsi256_si128(bIn1));
+  __m128i y = _mm_max_epi32(_mm256_extractf128_si256(bIn0, 1), _mm256_extractf128_si256(bIn1, 1));
+  *bOut = _mm256_insertf128_si256(_mm256_castsi128_si256(x), y, 1);
+#elif HV_SIMD_SSE
+  *bOut = _mm_max_epi32(bIn0, bIn1);
+#elif HV_SIMD_NEON
+  *bOut = vmaxq_s32(bIn0, bIn1);
+#else // HV_SIMD_NONE
+  *bOut = hv_max_i(bIn0, bIn1);
+#endif
+}
+
+static inline void __hv_pow_f(hv_bInf_t bIn0, hv_bInf_t bIn1, hv_bOutf_t bOut) {
+#if HV_SIMD_AVX
+  *bOut = _mm256_set_ps(
+      hv_pow_f(bIn0[7], bIn1[7]),
+      hv_pow_f(bIn0[6], bIn1[6]),
+      hv_pow_f(bIn0[5], bIn1[5]),
+      hv_pow_f(bIn0[4], bIn1[4]),
+      hv_pow_f(bIn0[3], bIn1[3]),
+      hv_pow_f(bIn0[2], bIn1[2]),
+      hv_pow_f(bIn0[1], bIn1[1]),
+      hv_pow_f(bIn0[0], bIn1[0]));
+#elif HV_SIMD_SSE
+  *bOut = _mm_set_ps(
+      hv_pow_f(bIn0[3], bIn1[3]),
+      hv_pow_f(bIn0[2], bIn1[2]),
+      hv_pow_f(bIn0[1], bIn1[1]),
+      hv_pow_f(bIn0[0], bIn1[0]));
+#elif HV_SIMD_NEON
+  *bOut = (float32x4_t) {
+      hv_pow_f(bIn0[0], bIn1[0]),
+      hv_pow_f(bIn0[1], bIn1[1]),
+      hv_pow_f(bIn0[2], bIn1[2]),
+      hv_pow_f(bIn0[3], bIn1[3])};
+#else // HV_SIMD_NONE
+  *bOut = hv_pow_f(bIn0, bIn1);
+#endif
+}
+
+static inline void __hv_gt_f(hv_bInf_t bIn0, hv_bInf_t bIn1, hv_bOutf_t bOut) {
+#if HV_SIMD_AVX
+  *bOut = _mm256_cmp_ps(bIn0, bIn1, _CMP_GT_OQ);
+#elif HV_SIMD_SSE
+  *bOut = _mm_cmpgt_ps(bIn0, bIn1);
+#elif HV_SIMD_NEON
+  *bOut = vreinterpretq_f32_u32(vcgtq_f32(bIn0, bIn1));
+#else // HV_SIMD_NONE
+  *bOut = (bIn0 > bIn1) ? 1.0f : 0.0f;
+#endif
+}
+
+static inline void __hv_gte_f(hv_bInf_t bIn0, hv_bInf_t bIn1, hv_bOutf_t bOut) {
+#if HV_SIMD_AVX
+  *bOut = _mm256_cmp_ps(bIn0, bIn1, _CMP_GE_OQ);
+#elif HV_SIMD_SSE
+  *bOut = _mm_cmpge_ps(bIn0, bIn1);
+#elif HV_SIMD_NEON
+  *bOut = vreinterpretq_f32_u32(vcgeq_f32(bIn0, bIn1));
+#else // HV_SIMD_NONE
+  *bOut = (bIn0 >= bIn1) ? 1.0f : 0.0f;
+#endif
+}
+
+static inline void __hv_lt_f(hv_bInf_t bIn0, hv_bInf_t bIn1, hv_bOutf_t bOut) {
+#if HV_SIMD_AVX
+  *bOut = _mm256_cmp_ps(bIn0, bIn1, _CMP_LT_OQ);
+#elif HV_SIMD_SSE
+  *bOut = _mm_cmplt_ps(bIn0, bIn1);
+#elif HV_SIMD_NEON
+  *bOut = vreinterpretq_f32_u32(vcltq_f32(bIn0, bIn1));
+#else // HV_SIMD_NONE
+  *bOut = (bIn0 < bIn1) ? 1.0f : 0.0f;
+#endif
+}
+
+static inline void __hv_lte_f(hv_bInf_t bIn0, hv_bInf_t bIn1, hv_bOutf_t bOut) {
+#if HV_SIMD_AVX
+  *bOut = _mm256_cmp_ps(bIn0, bIn1, _CMP_LE_OQ);
+#elif HV_SIMD_SSE
+  *bOut = _mm_cmple_ps(bIn0, bIn1);
+#elif HV_SIMD_NEON
+  *bOut = vreinterpretq_f32_u32(vcleq_f32(bIn0, bIn1));
+#else // HV_SIMD_NONE
+  *bOut = (bIn0 <= bIn1) ? 1.0f : 0.0f;
+#endif
+}
+
+static inline void __hv_neq_f(hv_bInf_t bIn0, hv_bInf_t bIn1, hv_bOutf_t bOut) {
+#if HV_SIMD_AVX
+  *bOut = _mm256_cmp_ps(bIn0, bIn1, _CMP_NEQ_OQ);
+#elif HV_SIMD_SSE
+  *bOut = _mm_cmpneq_ps(bIn0, bIn1);
+#elif HV_SIMD_NEON
+  *bOut = vreinterpretq_f32_u32(vmvnq_u32(vceqq_f32(bIn0, bIn1)));
+#else // HV_SIMD_NONE
+  *bOut = (bIn0 != bIn1) ? 1.0f : 0.0f;
+#endif
+}
+
+static inline void __hv_xor_f(hv_bInf_t bIn0, hv_bInf_t bIn1, hv_bOutf_t bOut) {
+#if HV_SIMD_AVX
+#warning __hv_xor_f() not implemented
+#elif HV_SIMD_SSE
+#warning __hv_xor_f() not implemented
+#elif HV_SIMD_NEON
+#warning __hv_xor_f() not implemented
+#else // HV_SIMD_NONE
+  *bOut = (float) (((int) bIn0) ^ ((int) bIn1));
+#endif
+}
+
+static inline void __hv_and_f(hv_bInf_t bIn0, hv_bInf_t bIn1, hv_bOutf_t bOut) {
+#if HV_SIMD_AVX
+  *bOut = _mm256_and_ps(bIn1, bIn0);
+#elif HV_SIMD_SSE
+  *bOut = _mm_and_ps(bIn1, bIn0);
+#elif HV_SIMD_NEON
+  *bOut = vreinterpretq_f32_u32(vandq_u32(vreinterpretq_u32_f32(bIn1), vreinterpretq_u32_f32(bIn0)));
+#else // HV_SIMD_NONE
+  if (bIn0 == 0.0f || bIn1 == 0.0f) *bOut = 0.0f;
+  else if (bIn0 == 1.0f) *bOut = bIn1;
+  else if (bIn1 == 1.0f) *bOut = bIn0;
+  else hv_assert(0); // NOTE(mhroth): floating point & is pretty much a bad idea, only used for if~
+#endif
+}
+
+// bOut = (bIn0 * bIn1) + bIn2
+static inline void __hv_fma_f(hv_bInf_t bIn0, hv_bInf_t bIn1, hv_bInf_t bIn2, hv_bOutf_t bOut) {
+#if HV_SIMD_AVX
+#if HV_SIMD_FMA
+  *bOut = _mm256_fmadd_ps(bIn0, bIn1, bIn2);
+#else
+  *bOut = _mm256_add_ps(_mm256_mul_ps(bIn0, bIn1), bIn2);
+#endif // HV_SIMD_FMA
+#elif HV_SIMD_SSE
+#if HV_SIMD_FMA
+  *bOut = _mm_fmadd_ps(bIn0, bIn1, bIn2);
+#else
+  *bOut = _mm_add_ps(_mm_mul_ps(bIn0, bIn1), bIn2);
+#endif // HV_SIMD_FMA
+#elif HV_SIMD_NEON
+#if __ARM_ARCH >= 8
+  *bOut = vfmaq_f32(bIn2, bIn0, bIn1);
+#else
+  // NOTE(mhroth): it turns out, fma SUUUUCKS on lesser ARM architectures
+  // But in fact ideally fma would be disabled in ir2c for ARM architectures.
+  // LLVM does a much better job handling fma than we do.
+  *bOut = vaddq_f32(vmulq_f32(bIn0, bIn1), bIn2);
+#endif
+#else // HV_SIMD_NONE
+  *bOut = hv_fma_f(bIn0, bIn1, bIn2);
+#endif
+}
+
+#endif // _HEAVY_MATH_H_
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/projects/heavy/envelopeTrigger/Heavy_bbb.h	Thu Nov 12 14:59:46 2015 +0000
@@ -0,0 +1,241 @@
+
+/**
+ * Copyright (c) 2014,2015 Enzien Audio, Ltd.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, and/or
+ * sublicense copies of the Software, strictly on a non-commercial basis,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * DO NOT MODIFY. THIS CODE IS MACHINE GENERATED BY THE SECTION6 HEAVY COMPILER.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "Utils.h"
+
+#if !HV_MSVC
+#pragma mark - Heavy Table
+#endif
+
+#ifndef _HEAVY_TABLE_H_
+#define _HEAVY_TABLE_H_
+
+typedef struct HvTable HvTable;
+
+/**
+ * Resizes the table to the given length. Length must be positive.
+ * Existing contents are copied to the new table. Remaining space is cleared.
+ * The change in byte-size of the table is returned. A value of zero indicates error.
+ */
+HV_EXPORT int hv_table_resize(HvTable *o, hv_uint32_t newLength);
+
+/** Returns a pointer to the raw buffer backing this table. DO NOT free it. */
+HV_EXPORT float *hv_table_getBuffer(HvTable *o);
+
+/** Returns the length of this table in samples. */
+HV_EXPORT int hv_table_getLength(HvTable *o);
+
+#endif // _HEAVY_TABLE_H_
+
+
+
+#if !HV_MSVC
+#pragma mark - Heavy Message
+#endif
+
+#ifndef _HEAVY_MESSAGE_H_
+#define _HEAVY_MESSAGE_H_
+
+HV_EXPORT typedef struct HvMessage HvMessage;
+
+/** Returns the byte size of a HvMessage with a number of elements on the heap. */
+HV_EXPORT hv_size_t hv_msg_getByteSize(int numElements);
+
+/** Create a HvMessage on the stack with a number of elements. This message MUST NOT be freed. */
+#define hv_msg_onStack(_n) ((HvMessage *) hv_alloca(hv_msg_getByteSize(_n)))
+
+/** Initialise a message with the number of elements and a timestamp (in milliseconds). */
+HV_EXPORT void hv_msg_init(HvMessage *m, int numElements, double timestamp);
+
+/** Returns the number of elements in this message. */
+HV_EXPORT int hv_msg_getNumElements(const HvMessage *const m);
+
+/** Returns the time at which this message exists (in milliseconds). */
+HV_EXPORT hv_uint32_t hv_msg_getTimestamp(const HvMessage *const m);
+
+/** Set the time at which this message should be executed (in milliseconds). */
+HV_EXPORT void hv_msg_setTimestamp(HvMessage *m, hv_uint32_t timestamp);
+
+/** Returns true of the indexed element is a bang. False otherwise. Index is not bounds checked. */
+HV_EXPORT bool hv_msg_isBang(const HvMessage *const m, int i);
+
+/** Sets the indexed element to a bang. Index is not bounds checked. */
+HV_EXPORT void hv_msg_setBang(HvMessage *m, int i);
+
+/** Returns true of the indexed element is a float. False otherwise. Index is not bounds checked. */
+HV_EXPORT bool hv_msg_isFloat(const HvMessage *const m, int i);
+
+/** Returns the indexed element as a float value. Index is not bounds checked. */
+HV_EXPORT float hv_msg_getFloat(const HvMessage *const m, int i);
+
+/** Sets the indexed element to float value. Index is not bounds checked. */
+HV_EXPORT void hv_msg_setFloat(HvMessage *m, int i, float f);
+
+/** Returns true of the indexed element is a symbol. False otherwise. Index is not bounds checked. */
+HV_EXPORT bool hv_msg_isSymbol(const HvMessage *const m, int i);
+
+/** Returns the indexed element as a symbol value. Index is not bounds checked. */
+HV_EXPORT char *hv_msg_getSymbol(const HvMessage *const m, int i);
+
+/** Returns true of the indexed element is a hash. False otherwise. Index is not bounds checked. */
+HV_EXPORT bool hv_msg_isHash(const HvMessage *const m, int i);
+
+/** Returns the indexed element as a hash value. Index is not bounds checked. */
+HV_EXPORT unsigned int hv_msg_getHash(const HvMessage *const m, int i);
+
+/** Sets the indexed element to symbol value. Index is not bounds checked. */
+HV_EXPORT void hv_msg_setSymbol(HvMessage *m, int i, const char *s);
+
+/**
+ * Returns true if the message has the given format, in number of elements and type. False otherwise.
+ * Valid element types are:
+ * 'b': bang
+ * 'f': float
+ * 's': symbol
+ *
+ * For example, a message with three floats would have a format of "fff". A single bang is "b".
+ * A message with two symbols is "ss". These types can be mixed and matched in any way.
+ */
+HV_EXPORT bool hv_msg_hasFormat(const HvMessage *const m, const char *fmt);
+
+/**
+ * Returns a basic string representation of the message.
+ * The character array MUST be deallocated by the caller.
+ */
+HV_EXPORT char *hv_msg_toString(const HvMessage *const m);
+
+/** Copy a message onto the stack. The message persists. */
+HV_EXPORT HvMessage *hv_msg_copy(const HvMessage *const m);
+
+/** Free a copied message. */
+HV_EXPORT void hv_msg_free(HvMessage *m);
+
+#endif // _HEAVY_MESSAGE_H_
+
+
+
+#if !HV_MSVC
+#pragma mark - Heavy Patch
+#endif
+
+#ifndef _HEAVY_BBB_H_
+#define _HEAVY_BBB_H_
+
+typedef struct Hv_bbb Hv_bbb;
+
+/**
+ * Creates a new patch instance.
+ * Sample rate should be positive and in Hertz.
+ */
+HV_EXPORT Hv_bbb *hv_bbb_new(double sampleRate);
+
+/**
+ * Creates a new patch instance.
+ * Sample rate should be positive and in Hertz.
+ * Pool size is in kilobytes, and determines the maximum amount of memory
+ *   allocated to messages at any time. By default this is 10.
+ */
+HV_EXPORT Hv_bbb *hv_bbb_new_with_pool(double sampleRate, int poolKb);
+
+/** Frees a patch instance. */
+HV_EXPORT void hv_bbb_free(Hv_bbb *c);
+
+/** Processes one block of samples for a patch instance. The buffer format is an array of float channel arrays. */
+HV_EXPORT int hv_bbb_process(Hv_bbb *c, float **const inputBuffers, float **const outputBuffers, int n4);
+
+/** Processes one block of samples for a patch instance. The buffer format is an uninterleaved float array of channels. */
+HV_EXPORT int hv_bbb_process_inline(Hv_bbb *c, float *const inputBuffers, float *const outputBuffers, int n4);
+
+/** Processes one block of samples for a patch instance. The buffer format is an interleaved short array of channels. */
+HV_EXPORT int hv_bbb_process_inline_short(Hv_bbb *c, short *const inputBuffers, short *const outputBuffers, int n4);
+#endif // _HEAVY_BBB_H_
+
+
+
+#if !HV_MSVC
+#pragma mark - Heavy Common
+#endif
+
+#ifndef _HEAVY_COMMON_H_
+#define _HEAVY_COMMON_H_
+
+typedef void Heavy;
+
+/** Returns the sample rate with which this patch has been configured. */
+HV_EXPORT double hv_getSampleRate(Heavy *c);
+
+/** Returns the number of input channels with which this patch has been configured. */
+HV_EXPORT int hv_getNumInputChannels(Heavy *c);
+
+/** Returns the number of output channels with which this patch has been configured. */
+HV_EXPORT int hv_getNumOutputChannels(Heavy *c);
+
+/** Set the print hook. The function is called whenever a message is sent to a print object. */
+HV_EXPORT void hv_setPrintHook(Heavy *c,
+    void (*f)(double timestamp, const char *printName, const char *message, void *userData));
+
+/**
+ * Set the send hook. The function is called whenever a message is sent to any send object.
+ * Messages returned by this function should NEVER be freed. If the message must persist, call
+ * hv_msg_copy() first.
+ */
+HV_EXPORT void hv_setSendHook(Heavy *c, void (*f)(double timestamp, const char *receiverName, const HvMessage *const m, void *userData));
+
+HV_EXPORT void hv_vscheduleMessageForReceiver(
+    Heavy *c, const char *receiverName, double delayMs, const char *format, ...);
+
+HV_EXPORT void hv_scheduleMessageForReceiver(Heavy *c, const char *receiverName, double delayMs, HvMessage *m);
+
+/** Cancels a previously scheduled message. */
+HV_EXPORT void hv_cancelMessage(Heavy *c, HvMessage *m);
+
+/** Returns a table object given its name. NULL if no table with that name exists. */
+HV_EXPORT HvTable *hv_getTableForName(Heavy *c, const char *tableName);
+
+/** Returns the current patch time in milliseconds. */
+HV_EXPORT double hv_getCurrentTime(Heavy *c);
+
+/** Sets a user-definable value. This value is never manipulated by Heavy. */
+HV_EXPORT void hv_setUserData(Heavy *c, void *userData);
+
+/** Returns the user-defined data. */
+HV_EXPORT void *hv_getUserData(Heavy *c);
+
+/** Define the base path of the patch. Used as the root path to locate assets. */
+HV_EXPORT void hv_setBasePath(Heavy *c, const char *basePath);
+
+/** Returns the read-only user-assigned name of this patch. */
+HV_EXPORT const char *hv_getName(Heavy *c);
+
+#endif // _HEAVY_COMMON_H_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/projects/heavy/envelopeTrigger/HvBase.c	Thu Nov 12 14:59:46 2015 +0000
@@ -0,0 +1,51 @@
+/**
+ * Copyright (c) 2014, 2015, Enzien Audio Ltd.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "HvBase.h"
+
+void ctx_setBasePath(HvBase *const _c, const char *basePath) {
+  hv_free(_c->basePath);
+  if (basePath != NULL) {
+    hv_size_t len = (hv_size_t) hv_strlen(basePath);
+    _c->basePath = (char *) hv_malloc((len+1)*sizeof(char));
+    hv_strncpy(_c->basePath, basePath, len);
+  }
+}
+
+void ctx_cancelMessage(HvBase *_c, HvMessage *m, void (*sendMessage)(HvBase *, int, const HvMessage *)) {
+  mq_removeMessage(&_c->mq, m, sendMessage);
+}
+
+void ctx_scheduleMessageForReceiverV(HvBase *const _c, const char *name,
+    const hv_uint32_t timestamp, const char *format, ...) {
+  va_list ap;
+  va_start(ap, format);
+
+  const int numElem = (int) hv_strlen(format);
+  HvMessage *m = HV_MESSAGE_ON_STACK(numElem);
+  msg_init(m, numElem, timestamp);
+  for (int i = 0; i < numElem; i++) {
+    switch (format[i]) {
+      case 'b': msg_setBang(m,i); break;
+      case 'f': msg_setFloat(m, i, (float) va_arg(ap, double)); break;
+      case 's': msg_setSymbol(m, i, (char *) va_arg(ap, char *)); break;
+      default: break;
+    }
+  }
+  _c->f_scheduleMessageForReceiver(_c, name, m);
+
+  va_end(ap);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/projects/heavy/envelopeTrigger/HvBase.h	Thu Nov 12 14:59:46 2015 +0000
@@ -0,0 +1,126 @@
+/**
+ * Copyright (c) 2014, 2015, Enzien Audio Ltd.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _HEAVY_BASE_H_
+#define _HEAVY_BASE_H_
+
+#include "MessageQueue.h"
+#include "Utils.h"
+
+#define Base(_x) ((HvBase *) _x)
+
+typedef struct HvBase {
+  int numInputChannels;
+  int numOutputChannels;
+  double sampleRate;
+  hv_uint32_t blockStartTimestamp;
+  unsigned int numBytes; // the total number of bytes allocated for this patch
+  void (*f_scheduleMessageForReceiver)(struct HvBase *const, const char *, HvMessage *);
+  struct HvTable *(*f_getTableForHash)(struct HvBase *const, hv_uint32_t);
+  MessageQueue mq;
+  void (*printHook)(double, const char *, const char *, void *);
+  void (*sendHook)(double, const char *, const HvMessage *const, void *);
+  char *basePath;
+  void *userData;
+  const char *name;
+} HvBase;
+
+/**
+ * Schedule a message in the message queue according to its timestamp.
+ * The copy of the message added to the queue is returned.
+ */
+static inline HvMessage *ctx_scheduleMessage(HvBase *_c, const HvMessage *const m,
+    void (*sendMessage)(HvBase *, int, const HvMessage *), int outletIndex) {
+  return mq_addMessageByTimestamp(&_c->mq, (HvMessage *) m, outletIndex, sendMessage);
+}
+
+static inline void ctx_scheduleMessageForReceiver(HvBase *const _c,
+    const char *name, HvMessage *m) {
+  _c->f_scheduleMessageForReceiver(_c, name, m);
+}
+
+void ctx_scheduleMessageForReceiverV(HvBase *const _c, const char *name,
+    const hv_uint32_t timestamp, const char *format, ...);
+
+void ctx_cancelMessage(HvBase *_c, HvMessage *m,
+    void (*sendMessage)(HvBase *, int, const HvMessage *));
+
+static inline int ctx_millisecondsToSamples(HvBase *_c, float timeInMs) {
+  return (int) (timeInMs * _c->sampleRate / 1000.0);
+}
+
+static inline double ctx_samplesToMilliseconds(HvBase *_c, int samples) {
+  return 1000.0 * samples / _c->sampleRate;
+}
+
+static inline double ctx_getSampleRate(HvBase *_c) {
+  return _c->sampleRate;
+}
+
+static inline int ctx_getNumInputChannels(HvBase *_c) {
+  return _c->numInputChannels;
+}
+
+static inline int ctx_getNumOutputChannels(HvBase *_c) {
+  return _c->numOutputChannels;
+}
+
+static inline const char *ctx_getName(HvBase *_c) {
+  return _c->name;
+}
+
+/** Returns the first sample of the block. */
+static inline hv_uint32_t ctx_getBlockStartTimestamp(HvBase *_c) {
+  return _c->blockStartTimestamp;
+}
+
+static inline void ctx_setPrintHook(HvBase *const _c, void (*f)(double,
+    const char *, const char *, void *)) {
+  _c->printHook = f;
+}
+
+static inline void ctx_setSendHook(HvBase *const _c, void (*f)(double, const char *, const HvMessage *const, void *)) {
+  _c->sendHook = f;
+}
+
+static inline void *ctx_getUserData(HvBase *const _c) {
+  return _c->userData;
+}
+
+static inline void ctx_setUserData(HvBase *const _c, void *userData) {
+  _c->userData = userData;
+}
+
+void ctx_setBasePath(HvBase *const _c, const char *basePath);
+
+static inline const char *ctx_getBasePath(HvBase *const _c) {
+  return _c->basePath;
+}
+
+static inline struct HvTable *ctx_getTableForHash(HvBase *const _c, hv_uint32_t h) {
+  return _c->f_getTableForHash(_c, h);
+}
+
+static inline struct HvTable *ctx_getTableForName(HvBase *const _c, const char *tableName) {
+  return ctx_getTableForHash(_c, msg_symbolToHash(tableName));
+}
+
+/** Returns the total number of bytes allocated for this patch. */
+static inline unsigned int ctx_getNumBytes(HvBase *_c) {
+  return _c->numBytes;
+}
+
+#endif // _HEAVY_BASE_H_
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/projects/heavy/envelopeTrigger/HvContext_bbb.c	Thu Nov 12 14:59:46 2015 +0000
@@ -0,0 +1,743 @@
+
+/**
+ * Copyright (c) 2014,2015 Enzien Audio, Ltd.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, and/or
+ * sublicense copies of the Software, strictly on a non-commercial basis,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * DO NOT MODIFY. THIS CODE IS MACHINE GENERATED BY THE SECTION6 HEAVY COMPILER.
+ */
+
+/*
+ * System Includes
+ */
+
+#include <assert.h>
+#include <math.h>
+#include <string.h>
+#include <stdarg.h>
+#include "HvContext_bbb.h"
+#include "HeavyMath.h"
+
+
+/*
+ * Function Declarations
+ */
+static const float hTable_Pcegq_data[512] = {0.0f, 0.0625f, 0.0883883f, 0.108253f, 0.125f, 0.139754f, 0.153093f, 0.165359f, 0.176777f, 0.1875f, 0.197642f, 0.207289f, 0.216506f, 0.225347f, 0.233854f, 0.242061f, 0.25f, 0.257694f, 0.265165f, 0.272431f, 0.279509f, 0.286411f, 0.293151f, 0.299739f, 0.306186f, 0.3125f, 0.318689f, 0.32476f, 0.330719f, 0.336573f, 0.342327f, 0.347985f, 0.353553f, 0.359035f, 0.364434f, 0.369755f, 0.375f, 0.380173f, 0.385276f, 0.390312f, 0.395285f, 0.400195f, 0.405046f, 0.40984f, 0.414578f, 0.419263f, 0.423896f, 0.428478f, 0.433013f, 0.4375f, 0.441942f, 0.446339f, 0.450694f, 0.455007f, 0.459279f, 0.463512f, 0.467707f, 0.471865f, 0.475986f, 0.480072f, 0.484123f, 0.488141f, 0.492125f, 0.496078f, 0.5f, 0.503891f, 0.507752f, 0.511585f, 0.515388f, 0.519164f, 0.522913f, 0.526634f, 0.53033f, 0.534f, 0.537645f, 0.541266f, 0.544862f, 0.548435f, 0.551985f, 0.555512f, 0.559017f, 0.5625f, 0.565962f, 0.569402f, 0.572822f, 0.576222f, 0.579601f, 0.582961f, 0.586302f, 0.589624f, 0.592927f, 0.596212f, 0.599479f, 0.602728f, 0.60596f, 0.609175f, 0.612372f, 0.615554f, 0.618718f, 0.621867f, 0.625f, 0.628117f, 0.631219f, 0.634306f, 0.637377f, 0.640434f, 0.643477f, 0.646505f, 0.649519f, 0.652519f, 0.655506f, 0.658478f, 0.661438f, 0.664384f, 0.667317f, 0.670238f, 0.673146f, 0.676041f, 0.678924f, 0.681795f, 0.684653f, 0.6875f, 0.690335f, 0.693159f, 0.695971f, 0.698771f, 0.701561f, 0.704339f, 0.707107f, 0.709864f, 0.71261f, 0.715345f, 0.71807f, 0.720785f, 0.72349f, 0.726184f, 0.728869f, 0.731544f, 0.734209f, 0.736864f, 0.73951f, 0.742146f, 0.744773f, 0.747391f, 0.75f, 0.7526f, 0.75519f, 0.757772f, 0.760345f, 0.76291f, 0.765466f, 0.768013f, 0.770552f, 0.773082f, 0.775605f, 0.778119f, 0.780625f, 0.783123f, 0.785613f, 0.788095f, 0.790569f, 0.793036f, 0.795495f, 0.797947f, 0.800391f, 0.802827f, 0.805256f, 0.807678f, 0.810093f, 0.8125f, 0.8149f, 0.817294f, 0.81968f, 0.822059f, 0.824432f, 0.826797f, 0.829156f, 0.831508f, 0.833854f, 0.836193f, 0.838525f, 0.840851f, 0.843171f, 0.845484f, 0.847791f, 0.850092f, 0.852386f, 0.854675f, 0.856957f, 0.859233f, 0.861503f, 0.863767f, 0.866025f, 0.868278f, 0.870524f, 0.872765f, 0.875f, 0.877229f, 0.879453f, 0.881671f, 0.883883f, 0.88609f, 0.888292f, 0.890488f, 0.892679f, 0.894864f, 0.897044f, 0.899218f, 0.901388f, 0.903552f, 0.905711f, 0.907865f, 0.910014f, 0.912157f, 0.914296f, 0.91643f, 0.918559f, 0.920682f, 0.922801f, 0.924916f, 0.927025f, 0.929129f, 0.931229f, 0.933324f, 0.935414f, 0.9375f, 0.939581f, 0.941657f, 0.943729f, 0.945797f, 0.947859f, 0.949918f, 0.951972f, 0.954021f, 0.956066f, 0.958107f, 0.960143f, 0.962175f, 0.964203f, 0.966227f, 0.968246f, 0.970261f, 0.972272f, 0.974279f, 0.976281f, 0.97828f, 0.980274f, 0.982265f, 0.984251f, 0.986233f, 0.988212f, 0.990186f, 0.992157f, 0.994123f, 0.996086f, 0.998045f, 1.0f, 0.992172f, 0.984375f, 0.976609f, 0.968874f, 0.961169f, 0.953495f, 0.945852f, 0.938239f, 0.930657f, 0.923106f, 0.915586f, 0.908097f, 0.900638f, 0.89321f, 0.885813f, 0.878447f, 0.871111f, 0.863806f, 0.856532f, 0.849289f, 0.842076f, 0.834894f, 0.827743f, 0.820623f, 0.813533f, 0.806474f, 0.799446f, 0.792449f, 0.785483f, 0.778547f, 0.771642f, 0.764767f, 0.757924f, 0.751111f, 0.744329f, 0.737578f, 0.730857f, 0.724168f, 0.717509f, 0.71088f, 0.704283f, 0.697716f, 0.69118f, 0.684675f, 0.678201f, 0.671757f, 0.665344f, 0.658962f, 0.652611f, 0.64629f, 0.64f, 0.633741f, 0.627513f, 0.621315f, 0.615148f, 0.609012f, 0.602907f, 0.596832f, 0.590788f, 0.584775f, 0.578793f, 0.572841f, 0.56692f, 0.56103f, 0.555171f, 0.549343f, 0.543545f, 0.537778f, 0.532041f, 0.526336f, 0.520661f, 0.515017f, 0.509404f, 0.503822f, 0.49827f, 0.492749f, 0.487259f, 0.481799f, 0.476371f, 0.470973f, 0.465605f, 0.460269f, 0.454963f, 0.449689f, 0.444444f, 0.439231f, 0.434048f, 0.428897f, 0.423775f, 0.418685f, 0.413625f, 0.408597f, 0.403599f, 0.398631f, 0.393695f, 0.388789f, 0.383914f, 0.37907f, 0.374256f, 0.369473f, 0.364721f, 0.36f, 0.355309f, 0.35065f, 0.346021f, 0.341423f, 0.336855f, 0.332318f, 0.327812f, 0.323337f, 0.318893f, 0.314479f, 0.310096f, 0.305744f, 0.301423f, 0.297132f, 0.292872f, 0.288643f, 0.284444f, 0.280277f, 0.27614f, 0.272034f, 0.267958f, 0.263914f, 0.2599f, 0.255917f, 0.251965f, 0.248043f, 0.244152f, 0.240292f, 0.236463f, 0.232664f, 0.228897f, 0.22516f, 0.221453f, 0.217778f, 0.214133f, 0.210519f, 0.206936f, 0.203383f, 0.199862f, 0.196371f, 0.19291f, 0.189481f, 0.186082f, 0.182714f, 0.179377f, 0.176071f, 0.172795f, 0.16955f, 0.166336f, 0.163153f, 0.16f, 0.156878f, 0.153787f, 0.150727f, 0.147697f, 0.144698f, 0.14173f, 0.138793f, 0.135886f, 0.13301f, 0.130165f, 0.127351f, 0.124567f, 0.121815f, 0.119093f, 0.116401f, 0.113741f, 0.111111f, 0.108512f, 0.105944f, 0.103406f, 0.1009f, 0.0984237f, 0.0959785f, 0.093564f, 0.0911803f, 0.0888274f, 0.0865052f, 0.0842138f, 0.0819531f, 0.0797232f, 0.077524f, 0.0753556f, 0.073218f, 0.0711111f, 0.069035f, 0.0669896f, 0.064975f, 0.0629911f, 0.0610381f, 0.0591157f, 0.0572241f, 0.0553633f, 0.0535332f, 0.0517339f, 0.0499654f, 0.0482276f, 0.0465206f, 0.0448443f, 0.0431988f, 0.041584f, 0.04f, 0.0384467f, 0.0369243f, 0.0354325f, 0.0339715f, 0.0325413f, 0.0311419f, 0.0297732f, 0.0284352f, 0.027128f, 0.0258516f, 0.0246059f, 0.023391f, 0.0222068f, 0.0210534f, 0.0199308f, 0.0188389f, 0.0177778f, 0.0167474f, 0.0157478f, 0.0147789f, 0.0138408f, 0.0129335f, 0.0120569f, 0.0112111f, 0.010396f, 0.00961169f, 0.00885813f, 0.00813533f, 0.00744329f, 0.00678201f, 0.00615148f, 0.00555171f, 0.0049827f, 0.00444444f, 0.00393695f, 0.00346021f, 0.00301423f, 0.002599f, 0.00221453f, 0.00186082f, 0.00153787f, 0.00124567f, 0.000984237f, 0.000753556f, 0.000553633f, 0.000384467f, 0.000246059f, 0.000138408f, 6.15148e-05f, 1.53787e-05f, 0.0f};
+static void cVar_rLv9w_sendMessage(HvBase *, int, const HvMessage *const);
+static void cSystem_tp4VA_sendMessage(HvBase *, int, const HvMessage *const);
+static void cVar_rQhd0_sendMessage(HvBase *, int, const HvMessage *const);
+static void cSlice_LzkmO_sendMessage(HvBase *, int, const HvMessage *const);
+static void cSwitchcase_y60Gw_onMessage(HvBase *, void *, int letIn, const HvMessage *const, void *);
+static void cLoadbang_TuCQI_sendMessage(HvBase *, int, const HvMessage *const);
+static void cBinop_ER1x8_sendMessage(HvBase *, int, const HvMessage *const);
+static void cMsg_oCnjm_sendMessage(HvBase *, int, const HvMessage *const);
+static void cSlice_HqIeY_sendMessage(HvBase *, int, const HvMessage *const);
+static void cVar_BTo3t_sendMessage(HvBase *, int, const HvMessage *const);
+static void cVar_ZzlGn_sendMessage(HvBase *, int, const HvMessage *const);
+static void cBinop_HqDsI_sendMessage(HvBase *, int, const HvMessage *const);
+static void cSwitchcase_EV1Bl_onMessage(HvBase *, void *, int letIn, const HvMessage *const, void *);
+static void cLoadbang_nVUh2_sendMessage(HvBase *, int, const HvMessage *const);
+static void cSystem_jIjhB_sendMessage(HvBase *, int, const HvMessage *const);
+static void cMsg_En77U_sendMessage(HvBase *, int, const HvMessage *const);
+static void cMsg_IbQ3q_sendMessage(HvBase *, int, const HvMessage *const);
+static void cSystem_zz1F7_sendMessage(HvBase *, int, const HvMessage *const);
+static void cBinop_oOwFV_sendMessage(HvBase *, int, const HvMessage *const);
+static void cBinop_P09tj_sendMessage(HvBase *, int, const HvMessage *const);
+static void cVar_NnTc2_sendMessage(HvBase *, int, const HvMessage *const);
+static void cLoadbang_2QoTi_sendMessage(HvBase *, int, const HvMessage *const);
+static void cBinop_f8PBr_sendMessage(HvBase *, int, const HvMessage *const);
+static void cMsg_qocid_sendMessage(HvBase *, int, const HvMessage *const);
+static void cBinop_ITJR9_sendMessage(HvBase *, int, const HvMessage *const);
+static void cUnop_nBNe2_sendMessage(HvBase *, int, const HvMessage *const);
+static void cSystem_ZnUnS_sendMessage(HvBase *, int, const HvMessage *const);
+static void cMsg_FhRde_sendMessage(HvBase *, int, const HvMessage *const);
+static void cBinop_cxljx_sendMessage(HvBase *, int, const HvMessage *const);
+static void cBinop_0UlVT_sendMessage(HvBase *, int, const HvMessage *const);
+static void cBinop_MJQIs_sendMessage(HvBase *, int, const HvMessage *const);
+static void cMsg_xzUtJ_sendMessage(HvBase *, int, const HvMessage *const);
+static void cBinop_a2rE6_sendMessage(HvBase *, int, const HvMessage *const);
+static void cBinop_govla_sendMessage(HvBase *, int, const HvMessage *const);
+static void cSlice_oxbrV_sendMessage(HvBase *, int, const HvMessage *const);
+static void cBinop_rzeQ2_sendMessage(HvBase *, int, const HvMessage *const);
+static void cSlice_yZctV_sendMessage(HvBase *, int, const HvMessage *const);
+static void cSlice_HCNcS_sendMessage(HvBase *, int, const HvMessage *const);
+static void cVar_ItOCU_sendMessage(HvBase *, int, const HvMessage *const);
+static void cSlice_Nx0UC_sendMessage(HvBase *, int, const HvMessage *const);
+static void cLoadbang_4O9oF_sendMessage(HvBase *, int, const HvMessage *const);
+static void cVar_VE9tg_sendMessage(HvBase *, int, const HvMessage *const);
+static void cBinop_RE1w0_sendMessage(HvBase *, int, const HvMessage *const);
+static void cSlice_Pkd46_sendMessage(HvBase *, int, const HvMessage *const);
+static void cLoadbang_KAaax_sendMessage(HvBase *, int, const HvMessage *const);
+
+
+
+/*
+ * Static Helper Functions
+ */
+
+static void ctx_intern_scheduleMessageForReceiver(
+    HvBase *const _c, const char *name, HvMessage *m) {
+  switch (msg_symbolToHash(name)) {
+    default: return;
+  }
+}
+
+static struct HvTable *ctx_intern_getTableForHash(HvBase *const _c, hv_uint32_t h) {
+  switch (h) {
+    case 0xB6D0D974: return &Context(_c)->hTable_Pcegq; // env1
+    default: return NULL;
+  }
+}
+
+
+
+/*
+ * Context Include and Implementatons
+ */
+
+Hv_bbb *hv_bbb_new_with_pool(double sampleRate, int poolKb) {
+  hv_assert(sampleRate > 0.0); // can't initialise with sampling rate of 0
+  hv_assert(poolKb >= 1); // a message pool of some reasonable size is always needed
+  Hv_bbb *const _c = (Hv_bbb *) hv_malloc(sizeof(Hv_bbb));
+
+  Base(_c)->numInputChannels = 10;
+  Base(_c)->numOutputChannels = 2;
+  Base(_c)->sampleRate = sampleRate;
+  Base(_c)->blockStartTimestamp = 0;
+  Base(_c)->f_scheduleMessageForReceiver = &ctx_intern_scheduleMessageForReceiver;
+  Base(_c)->f_getTableForHash = &ctx_intern_getTableForHash;
+  mq_initWithPoolSize(&Base(_c)->mq, poolKb);
+  Base(_c)->basePath = NULL;
+  Base(_c)->printHook = NULL;
+  Base(_c)->sendHook = NULL;
+  Base(_c)->userData = NULL;
+  Base(_c)->name = "bbb";
+
+  Base(_c)->numBytes = sizeof(Hv_bbb);
+  Base(_c)->numBytes += sVarf_init(&_c->sVarf_DIQHM, 1.0f, 0.0f, false);
+  Base(_c)->numBytes += sVarf_init(&_c->sVarf_EIzJc, 44100.0f, 0.0f, false);
+  Base(_c)->numBytes += sVarf_init(&_c->sVarf_J0BAW, 0.0f, 0.0f, false);
+  Base(_c)->numBytes += sRPole_init(&_c->sRPole_vtJYw);
+  Base(_c)->numBytes += sVarf_init(&_c->sVarf_haFXq, 1.0f, 0.0f, false);
+  Base(_c)->numBytes += sDel1_init(&_c->sDel1_8dkfF);
+  Base(_c)->numBytes += sVarf_init(&_c->sVarf_4RU63, 0.0f, 0.0f, false);
+  Base(_c)->numBytes += sVarf_init(&_c->sVarf_5BIjv, 0.0f, 0.0f, false);
+  Base(_c)->numBytes += sVarf_init(&_c->sVarf_82QyC, -1e-37f, 0.0f, false);
+  Base(_c)->numBytes += sBiquad_k_init(&_c->sBiquad_k_8Keaz, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f);
+  Base(_c)->numBytes += sVarf_init(&_c->sVarf_2muG8, 0.5f, 0.0f, false);
+  Base(_c)->numBytes += sVarf_init(&_c->sVarf_YrcAl, 0.0f, 0.0f, false);
+  Base(_c)->numBytes += sVarf_init(&_c->sVarf_1pbLN, -1e-37f, 0.0f, false);
+  Base(_c)->numBytes += sRPole_init(&_c->sRPole_Q5SA1);
+  Base(_c)->numBytes += sVarf_init(&_c->sVarf_ZTuE8, 1.0f, 0.0f, false);
+  Base(_c)->numBytes += sVarf_init(&_c->sVarf_9Q4iz, 0.0f, 0.0f, false);
+  Base(_c)->numBytes += sVarf_init(&_c->sVarf_QHeut, 1.0f, 0.0f, false);
+  Base(_c)->numBytes += sVarf_init(&_c->sVarf_BWg3y, 100000.0f, 0.0f, false);
+  Base(_c)->numBytes += sVarf_init(&_c->sVarf_yW7Co, 1e-05f, 0.0f, false);
+  Base(_c)->numBytes += sVarf_init(&_c->sVarf_BMuCC, 0.0f, 0.0f, false);
+  Base(_c)->numBytes += sVarf_init(&_c->sVarf_1vLiI, 0.0f, 0.0f, false);
+  Base(_c)->numBytes += sVarf_init(&_c->sVarf_ZKIZB, 0.0f, 0.0f, false);
+  Base(_c)->numBytes += sVarf_init(&_c->sVarf_SmDJi, 0.0f, 0.0f, false);
+  Base(_c)->numBytes += sTabread_init(&_c->sTabread_ef8Y2, &_c->hTable_Pcegq, false);
+  Base(_c)->numBytes += sVarf_init(&_c->sVarf_Z1CfH, 0.0f, 0.0f, false);
+  Base(_c)->numBytes += sTabread_init(&_c->sTabread_nnJuj, &_c->hTable_Pcegq, false);
+  Base(_c)->numBytes += sVarf_init(&_c->sVarf_CwdRa, 0.0f, 0.0f, false);
+  Base(_c)->numBytes += sVarf_init(&_c->sVarf_z5YqL, 0.0f, 0.0f, false);
+  Base(_c)->numBytes += sVarf_init(&_c->sVarf_AMYc1, 0.0f, 0.0f, false);
+  Base(_c)->numBytes += sVarf_init(&_c->sVarf_yGh3v, 0.0f, 0.0f, false);
+  Base(_c)->numBytes += sVarf_init(&_c->sVarf_ThV6W, 0.0f, 0.0f, false);
+  Base(_c)->numBytes += sVarf_init(&_c->sVarf_U0HuI, 0.0f, 0.0f, false);
+  Base(_c)->numBytes += sTabread_init(&_c->sTabread_g0gGp, &_c->hTable_Pcegq, false);
+  Base(_c)->numBytes += sVarf_init(&_c->sVarf_rLY2o, 0.0f, 0.0f, false);
+  Base(_c)->numBytes += sTabread_init(&_c->sTabread_joe74, &_c->hTable_Pcegq, false);
+  Base(_c)->numBytes += sVarf_init(&_c->sVarf_tTp9Q, 0.0f, 0.0f, false);
+  Base(_c)->numBytes += sVarf_init(&_c->sVarf_Ip7Ud, 0.0f, 0.0f, false);
+  Base(_c)->numBytes += sPhasor_init(&_c->sPhasor_KqGIr, sampleRate);
+  Base(_c)->numBytes += hTable_initWithData(&_c->hTable_Pcegq, 512, hTable_Pcegq_data);
+  Base(_c)->numBytes += cVar_init_s(&_c->cVar_rLv9w, "env1");
+  Base(_c)->numBytes += cVar_init_f(&_c->cVar_rQhd0, 0.0f);
+  Base(_c)->numBytes += cSlice_init(&_c->cSlice_LzkmO, 1, 1);
+  Base(_c)->numBytes += cSlice_init(&_c->cSlice_HqIeY, 1, 1);
+  Base(_c)->numBytes += cVar_init_s(&_c->cVar_BTo3t, "env1");
+  Base(_c)->numBytes += cVar_init_f(&_c->cVar_ZzlGn, 0.0f);
+  Base(_c)->numBytes += cVar_init_f(&_c->cVar_NnTc2, 1.0f);
+  Base(_c)->numBytes += cBinop_init(&_c->cBinop_ITJR9, 0.0f); // __div
+  Base(_c)->numBytes += cBinop_init(&_c->cBinop_cxljx, 0.0f); // __mul
+  Base(_c)->numBytes += cBinop_init(&_c->cBinop_0UlVT, 1.0f); // __min
+  Base(_c)->numBytes += cBinop_init(&_c->cBinop_MJQIs, 0.0f); // __max
+  Base(_c)->numBytes += cSlice_init(&_c->cSlice_oxbrV, 2, 1);
+  Base(_c)->numBytes += cSlice_init(&_c->cSlice_yZctV, 3, 1);
+  Base(_c)->numBytes += cSlice_init(&_c->cSlice_HCNcS, 4, 1);
+  Base(_c)->numBytes += cVar_init_f(&_c->cVar_ItOCU, 0.0f);
+  Base(_c)->numBytes += cSlice_init(&_c->cSlice_Nx0UC, 0, 1);
+  Base(_c)->numBytes += cVar_init_f(&_c->cVar_VE9tg, 0.0f);
+  Base(_c)->numBytes += cSlice_init(&_c->cSlice_Pkd46, 1, 1);
+
+  // loadbang
+  ctx_scheduleMessage(Base(_c), msg_initWithBang(HV_MESSAGE_ON_STACK(1), 0), &cLoadbang_2QoTi_sendMessage, 0);
+  ctx_scheduleMessage(Base(_c), msg_initWithBang(HV_MESSAGE_ON_STACK(1), 0), &cLoadbang_4O9oF_sendMessage, 0);
+  ctx_scheduleMessage(Base(_c), msg_initWithBang(HV_MESSAGE_ON_STACK(1), 0), &cLoadbang_KAaax_sendMessage, 0);
+  ctx_scheduleMessage(Base(_c), msg_initWithBang(HV_MESSAGE_ON_STACK(1), 0), &cLoadbang_TuCQI_sendMessage, 0);
+  ctx_scheduleMessage(Base(_c), msg_initWithBang(HV_MESSAGE_ON_STACK(1), 0), &cLoadbang_nVUh2_sendMessage, 0);
+
+  return _c;
+}
+
+Hv_bbb *hv_bbb_new(double sampleRate) {
+  return hv_bbb_new_with_pool(sampleRate, 10); // default to 10KB MessagePool
+}
+
+void hv_bbb_free(Hv_bbb *_c) {
+  hTable_free(&_c->hTable_Pcegq);
+
+  hv_free(Base(_c)->basePath);
+  mq_free(&Base(_c)->mq); // free queue after all objects have been freed, messages may be cancelled
+
+  hv_free(_c);
+}
+
+
+
+/*
+ * Static Function Implementation
+ */
+static void hTable_Pcegq_sendMessage(HvBase *_c, int letIn, const HvMessage *const m) {
+}
+
+static void cVar_rLv9w_sendMessage(HvBase *_c, int letIn, const HvMessage *const m) {
+  cMsg_oCnjm_sendMessage(_c, 0, m);
+}
+
+static void cSystem_tp4VA_sendMessage(HvBase *_c, int letIn, const HvMessage *const m) {
+  cBinop_k_onMessage(_c, NULL, HV_BINOP_SUBTRACT, 2.0f, 0, m, &cBinop_ER1x8_sendMessage);
+}
+
+static void cVar_rQhd0_sendMessage(HvBase *_c, int letIn, const HvMessage *const m) {
+  cBinop_k_onMessage(_c, NULL, HV_BINOP_SUBTRACT, 2.0f, 0, m, &cBinop_ER1x8_sendMessage);
+}
+
+static void cSlice_LzkmO_sendMessage(HvBase *_c, int letIn, const HvMessage *const m) {
+  switch(letIn) {
+    case 0: {
+      sTabread_onMessage(_c, &Context(_c)->sTabread_ef8Y2, 1, m);
+      sTabread_onMessage(_c, &Context(_c)->sTabread_nnJuj, 1, m);
+      cVar_onMessage(_c, &Context(_c)->cVar_rLv9w, 0, m, &cVar_rLv9w_sendMessage);
+      break;
+    }
+    case 1: {
+      break;
+    }
+    default: return;
+  }
+}
+
+static void cSwitchcase_y60Gw_onMessage(HvBase *_c, void *o, int letIn, const HvMessage *const m, void *sendMessage) {
+  switch (msg_getHash(m,0)) {
+    case 0x3E004DAB: { // "set"
+      cSlice_onMessage(_c, &Context(_c)->cSlice_LzkmO, 0, m, &cSlice_LzkmO_sendMessage);
+      break;
+    }
+    default: {
+      break;
+    }
+  }
+}
+
+static void cLoadbang_TuCQI_sendMessage(HvBase *_c, int letIn, const HvMessage *const m) {
+  cVar_onMessage(_c, &Context(_c)->cVar_rLv9w, 0, m, &cVar_rLv9w_sendMessage);
+}
+
+static void cBinop_ER1x8_sendMessage(HvBase *_c, int letIn, const HvMessage *const m) {
+  sVarf_onMessage(_c, &Context(_c)->sVarf_SmDJi, m);
+}
+
+static void cMsg_oCnjm_sendMessage(HvBase *_c, int letIn, const HvMessage *const n) {
+  HvMessage *m = NULL;
+  m = HV_MESSAGE_ON_STACK(3);
+  msg_init(m, 3, msg_getTimestamp(n));
+  msg_setSymbol(m, 0, "table");
+  msg_setElementToFrom(m, 1, n, 0);
+  msg_setSymbol(m, 2, "size");
+  cSystem_onMessage(_c, NULL, 0, m, &cSystem_tp4VA_sendMessage);
+}
+
+static void cSlice_HqIeY_sendMessage(HvBase *_c, int letIn, const HvMessage *const m) {
+  switch(letIn) {
+    case 0: {
+      sTabread_onMessage(_c, &Context(_c)->sTabread_g0gGp, 1, m);
+      sTabread_onMessage(_c, &Context(_c)->sTabread_joe74, 1, m);
+      cVar_onMessage(_c, &Context(_c)->cVar_BTo3t, 0, m, &cVar_BTo3t_sendMessage);
+      break;
+    }
+    case 1: {
+      break;
+    }
+    default: return;
+  }
+}
+
+static void cVar_BTo3t_sendMessage(HvBase *_c, int letIn, const HvMessage *const m) {
+  cMsg_En77U_sendMessage(_c, 0, m);
+}
+
+static void cVar_ZzlGn_sendMessage(HvBase *_c, int letIn, const HvMessage *const m) {
+  cBinop_k_onMessage(_c, NULL, HV_BINOP_SUBTRACT, 2.0f, 0, m, &cBinop_HqDsI_sendMessage);
+}
+
+static void cBinop_HqDsI_sendMessage(HvBase *_c, int letIn, const HvMessage *const m) {
+  sVarf_onMessage(_c, &Context(_c)->sVarf_U0HuI, m);
+}
+
+static void cSwitchcase_EV1Bl_onMessage(HvBase *_c, void *o, int letIn, const HvMessage *const m, void *sendMessage) {
+  switch (msg_getHash(m,0)) {
+    case 0x3E004DAB: { // "set"
+      cSlice_onMessage(_c, &Context(_c)->cSlice_HqIeY, 0, m, &cSlice_HqIeY_sendMessage);
+      break;
+    }
+    default: {
+      break;
+    }
+  }
+}
+
+static void cLoadbang_nVUh2_sendMessage(HvBase *_c, int letIn, const HvMessage *const m) {
+  cVar_onMessage(_c, &Context(_c)->cVar_BTo3t, 0, m, &cVar_BTo3t_sendMessage);
+}
+
+static void cSystem_jIjhB_sendMessage(HvBase *_c, int letIn, const HvMessage *const m) {
+  cBinop_k_onMessage(_c, NULL, HV_BINOP_SUBTRACT, 2.0f, 0, m, &cBinop_HqDsI_sendMessage);
+}
+
+static void cMsg_En77U_sendMessage(HvBase *_c, int letIn, const HvMessage *const n) {
+  HvMessage *m = NULL;
+  m = HV_MESSAGE_ON_STACK(3);
+  msg_init(m, 3, msg_getTimestamp(n));
+  msg_setSymbol(m, 0, "table");
+  msg_setElementToFrom(m, 1, n, 0);
+  msg_setSymbol(m, 2, "size");
+  cSystem_onMessage(_c, NULL, 0, m, &cSystem_jIjhB_sendMessage);
+}
+
+static void cMsg_IbQ3q_sendMessage(HvBase *_c, int letIn, const HvMessage *const n) {
+  HvMessage *m = NULL;
+  m = HV_MESSAGE_ON_STACK(1);
+  msg_init(m, 1, msg_getTimestamp(n));
+  msg_setSymbol(m, 0, "samplerate");
+  cSystem_onMessage(_c, NULL, 0, m, &cSystem_zz1F7_sendMessage);
+}
+
+static void cSystem_zz1F7_sendMessage(HvBase *_c, int letIn, const HvMessage *const m) {
+  sVarf_onMessage(_c, &Context(_c)->sVarf_EIzJc, m);
+}
+
+static void cBinop_oOwFV_sendMessage(HvBase *_c, int letIn, const HvMessage *const m) {
+  cBinop_k_onMessage(_c, NULL, HV_BINOP_MULTIPLY, 0.5f, 0, m, &cBinop_a2rE6_sendMessage);
+}
+
+static void cBinop_P09tj_sendMessage(HvBase *_c, int letIn, const HvMessage *const m) {
+  sVarf_onMessage(_c, &Context(_c)->sVarf_J0BAW, m);
+}
+
+static void cVar_NnTc2_sendMessage(HvBase *_c, int letIn, const HvMessage *const m) {
+  cBinop_onMessage(_c, &Context(_c)->cBinop_cxljx, HV_BINOP_MULTIPLY, 0, m, &cBinop_cxljx_sendMessage);
+}
+
+static void cLoadbang_2QoTi_sendMessage(HvBase *_c, int letIn, const HvMessage *const m) {
+  cMsg_FhRde_sendMessage(_c, 0, m);
+  cVar_onMessage(_c, &Context(_c)->cVar_NnTc2, 0, m, &cVar_NnTc2_sendMessage);
+}
+
+static void cBinop_f8PBr_sendMessage(HvBase *_c, int letIn, const HvMessage *const m) {
+  cBinop_onMessage(_c, &Context(_c)->cBinop_ITJR9, HV_BINOP_DIVIDE, 0, m, &cBinop_ITJR9_sendMessage);
+}
+
+static void cMsg_qocid_sendMessage(HvBase *_c, int letIn, const HvMessage *const n) {
+  HvMessage *m = NULL;
+  m = HV_MESSAGE_ON_STACK(1);
+  msg_init(m, 1, msg_getTimestamp(n));
+  msg_setFloat(m, 0, 1.0f);
+  cUnop_onMessage(_c, HV_UNOP_ATAN, m, &cUnop_nBNe2_sendMessage);
+}
+
+static void cBinop_ITJR9_sendMessage(HvBase *_c, int letIn, const HvMessage *const m) {
+  cBinop_onMessage(_c, &Context(_c)->cBinop_cxljx, HV_BINOP_MULTIPLY, 1, m, &cBinop_cxljx_sendMessage);
+}
+
+static void cUnop_nBNe2_sendMessage(HvBase *_c, int letIn, const HvMessage *const m) {
+  cBinop_k_onMessage(_c, NULL, HV_BINOP_MULTIPLY, 8.0f, 0, m, &cBinop_f8PBr_sendMessage);
+}
+
+static void cSystem_ZnUnS_sendMessage(HvBase *_c, int letIn, const HvMessage *const m) {
+  cBinop_onMessage(_c, &Context(_c)->cBinop_ITJR9, HV_BINOP_DIVIDE, 1, m, &cBinop_ITJR9_sendMessage);
+  cMsg_qocid_sendMessage(_c, 0, m);
+}
+
+static void cMsg_FhRde_sendMessage(HvBase *_c, int letIn, const HvMessage *const n) {
+  HvMessage *m = NULL;
+  m = HV_MESSAGE_ON_STACK(1);
+  msg_init(m, 1, msg_getTimestamp(n));
+  msg_setSymbol(m, 0, "samplerate");
+  cSystem_onMessage(_c, NULL, 0, m, &cSystem_ZnUnS_sendMessage);
+}
+
+static void cBinop_cxljx_sendMessage(HvBase *_c, int letIn, const HvMessage *const m) {
+  cMsg_xzUtJ_sendMessage(_c, 0, m);
+}
+
+static void cBinop_0UlVT_sendMessage(HvBase *_c, int letIn, const HvMessage *const m) {
+  cBinop_onMessage(_c, &Context(_c)->cBinop_MJQIs, HV_BINOP_MAX, 0, m, &cBinop_MJQIs_sendMessage);
+}
+
+static void cBinop_MJQIs_sendMessage(HvBase *_c, int letIn, const HvMessage *const m) {
+  cBinop_k_onMessage(_c, NULL, HV_BINOP_ADD, 1.0f, 0, m, &cBinop_oOwFV_sendMessage);
+  cBinop_k_onMessage(_c, NULL, HV_BINOP_MULTIPLY, -1.0f, 0, m, &cBinop_P09tj_sendMessage);
+}
+
+static void cMsg_xzUtJ_sendMessage(HvBase *_c, int letIn, const HvMessage *const n) {
+  HvMessage *m = NULL;
+  m = HV_MESSAGE_ON_STACK(2);
+  msg_init(m, 2, msg_getTimestamp(n));
+  msg_setFloat(m, 0, 1.0f);
+  msg_setElementToFrom(m, 1, n, 0);
+  cBinop_k_onMessage(_c, NULL, HV_BINOP_SUBTRACT, 0.0f, 0, m, &cBinop_govla_sendMessage);
+}
+
+static void cBinop_a2rE6_sendMessage(HvBase *_c, int letIn, const HvMessage *const m) {
+  sVarf_onMessage(_c, &Context(_c)->sVarf_4RU63, m);
+}
+
+static void cBinop_govla_sendMessage(HvBase *_c, int letIn, const HvMessage *const m) {
+  cBinop_onMessage(_c, &Context(_c)->cBinop_0UlVT, HV_BINOP_MIN, 0, m, &cBinop_0UlVT_sendMessage);
+}
+
+static void cSlice_oxbrV_sendMessage(HvBase *_c, int letIn, const HvMessage *const m) {
+  switch(letIn) {
+    case 0: {
+      sBiquad_k_onMessage(&Context(_c)->sBiquad_k_8Keaz, 1, m);
+      break;
+    }
+    case 1: {
+      break;
+    }
+    default: return;
+  }
+}
+
+static void cBinop_rzeQ2_sendMessage(HvBase *_c, int letIn, const HvMessage *const m) {
+  sBiquad_k_onMessage(&Context(_c)->sBiquad_k_8Keaz, 4, m);
+}
+
+static void cSlice_yZctV_sendMessage(HvBase *_c, int letIn, const HvMessage *const m) {
+  switch(letIn) {
+    case 0: {
+      sBiquad_k_onMessage(&Context(_c)->sBiquad_k_8Keaz, 2, m);
+      break;
+    }
+    case 1: {
+      break;
+    }
+    default: return;
+  }
+}
+
+static void cSlice_HCNcS_sendMessage(HvBase *_c, int letIn, const HvMessage *const m) {
+  switch(letIn) {
+    case 0: {
+      sBiquad_k_onMessage(&Context(_c)->sBiquad_k_8Keaz, 3, m);
+      break;
+    }
+    case 1: {
+      break;
+    }
+    default: return;
+  }
+}
+
+static void cVar_ItOCU_sendMessage(HvBase *_c, int letIn, const HvMessage *const m) {
+  cBinop_k_onMessage(_c, NULL, HV_BINOP_MULTIPLY, -1.0f, 0, m, &cBinop_RE1w0_sendMessage);
+}
+
+static void cSlice_Nx0UC_sendMessage(HvBase *_c, int letIn, const HvMessage *const m) {
+  switch(letIn) {
+    case 0: {
+      cBinop_k_onMessage(_c, NULL, HV_BINOP_MULTIPLY, -1.0f, 0, m, &cBinop_rzeQ2_sendMessage);
+      break;
+    }
+    case 1: {
+      break;
+    }
+    default: return;
+  }
+}
+
+static void cLoadbang_4O9oF_sendMessage(HvBase *_c, int letIn, const HvMessage *const m) {
+  cVar_onMessage(_c, &Context(_c)->cVar_VE9tg, 0, m, &cVar_VE9tg_sendMessage);
+  cVar_onMessage(_c, &Context(_c)->cVar_ItOCU, 0, m, &cVar_ItOCU_sendMessage);
+}
+
+static void cVar_VE9tg_sendMessage(HvBase *_c, int letIn, const HvMessage *const m) {
+  cBinop_k_onMessage(_c, NULL, HV_BINOP_MULTIPLY, -1.0f, 0, m, &cBinop_rzeQ2_sendMessage);
+}
+
+static void cBinop_RE1w0_sendMessage(HvBase *_c, int letIn, const HvMessage *const m) {
+  sBiquad_k_onMessage(&Context(_c)->sBiquad_k_8Keaz, 5, m);
+}
+
+static void cSlice_Pkd46_sendMessage(HvBase *_c, int letIn, const HvMessage *const m) {
+  switch(letIn) {
+    case 0: {
+      cBinop_k_onMessage(_c, NULL, HV_BINOP_MULTIPLY, -1.0f, 0, m, &cBinop_RE1w0_sendMessage);
+      break;
+    }
+    case 1: {
+      break;
+    }
+    default: return;
+  }
+}
+
+static void cLoadbang_KAaax_sendMessage(HvBase *_c, int letIn, const HvMessage *const m) {
+  cMsg_IbQ3q_sendMessage(_c, 0, m);
+}
+
+
+
+
+/*
+ * Context Process Implementation
+ */
+
+int hv_bbb_process(Hv_bbb *const _c, float **const inputBuffers, float **const outputBuffers, int nx) {
+  const int n4 = nx & ~HV_N_SIMD_MASK; // ensure that the block size is a multiple of HV_N_SIMD
+
+  // temporary signal vars
+  hv_bufferf_t Bf0, Bf1, Bf2, Bf3, Bf4, Bf5, Bf6, Bf7;
+  hv_bufferi_t Bi0, Bi1;
+
+  // input and output vars
+  hv_bufferf_t O0, O1;
+  hv_bufferf_t I0, I1, I2, I3, I4, I5, I6, I7, I8, I9;
+
+  // declare and init the zero buffer
+  hv_bufferf_t ZERO; __hv_zero_f(VOf(ZERO));
+
+  hv_uint32_t nextBlock = Base(_c)->blockStartTimestamp;
+  for (int n = 0; n < n4; n += HV_N_SIMD) {
+
+    // process all of the messages for this block
+    nextBlock += HV_N_SIMD;
+    while (mq_hasMessageBefore(&Base(_c)->mq, nextBlock)) {
+      MessageNode *const node = mq_peek(&Base(_c)->mq);
+      node->sendMessage(Base(_c), node->let, node->m);
+      mq_pop(&Base(_c)->mq);
+    }
+
+    // load input buffers
+    __hv_load_f(inputBuffers[0]+n, VOf(I0));
+    __hv_load_f(inputBuffers[1]+n, VOf(I1));
+    __hv_load_f(inputBuffers[2]+n, VOf(I2));
+    __hv_load_f(inputBuffers[3]+n, VOf(I3));
+    __hv_load_f(inputBuffers[4]+n, VOf(I4));
+    __hv_load_f(inputBuffers[5]+n, VOf(I5));
+    __hv_load_f(inputBuffers[6]+n, VOf(I6));
+    __hv_load_f(inputBuffers[7]+n, VOf(I7));
+    __hv_load_f(inputBuffers[8]+n, VOf(I8));
+    __hv_load_f(inputBuffers[9]+n, VOf(I9));
+
+    // zero output buffers
+    __hv_zero_f(VOf(O0));
+    __hv_zero_f(VOf(O1));
+
+    // process all signal functions
+    __hv_var_f(&_c->sVarf_DIQHM, VOf(Bf0));
+    __hv_var_f(&_c->sVarf_EIzJc, VOf(Bf1));
+    __hv_div_f(VIf(Bf0), VIf(Bf1), VOf(Bf1));
+    __hv_var_f(&_c->sVarf_J0BAW, VOf(Bf0));
+    __hv_rpole_f(&_c->sRPole_vtJYw, VIf(I7), VIf(Bf0), VOf(Bf0));
+    __hv_var_f(&_c->sVarf_haFXq, VOf(Bf2));
+    __hv_del1_f(&_c->sDel1_8dkfF, VIf(Bf0), VOf(Bf3));
+    __hv_mul_f(VIf(Bf3), VIf(Bf2), VOf(Bf2));
+    __hv_sub_f(VIf(Bf0), VIf(Bf2), VOf(Bf2));
+    __hv_var_f(&_c->sVarf_4RU63, VOf(Bf0));
+    __hv_mul_f(VIf(Bf2), VIf(Bf0), VOf(Bf0));
+    __hv_abs_f(VIf(Bf0), VOf(Bf0));
+    __hv_min_f(VIf(Bf0), VIf(I8), VOf(Bf0));
+    __hv_sub_f(VIf(Bf0), VIf(I8), VOf(Bf0));
+    __hv_var_f(&_c->sVarf_5BIjv, VOf(Bf2));
+    __hv_min_f(VIf(Bf0), VIf(Bf2), VOf(Bf2));
+    __hv_var_f(&_c->sVarf_82QyC, VOf(Bf0));
+    __hv_max_f(VIf(Bf2), VIf(Bf0), VOf(Bf0));
+    __hv_var_k_f(VOf(Bf2), 1e-37f, 1e-37f, 1e-37f, 1e-37f, 1e-37f, 1e-37f, 1e-37f, 1e-37f, 0);
+    __hv_add_f(VIf(Bf0), VIf(Bf2), VOf(Bf2));
+    __hv_var_k_f(VOf(Bf0), 1e+37f, 1e+37f, 1e+37f, 1e+37f, 1e+37f, 1e+37f, 1e+37f, 1e+37f, 0);
+    __hv_mul_f(VIf(Bf2), VIf(Bf0), VOf(Bf0));
+    __hv_biquad_k_f(&_c->sBiquad_k_8Keaz, VIf(Bf0), VOf(Bf2));
+    __hv_var_k_f(VOf(Bf3), -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 0);
+    __hv_mul_f(VIf(Bf2), VIf(Bf3), VOf(Bf3));
+    __hv_var_f(&_c->sVarf_2muG8, VOf(Bf2));
+    __hv_max_f(VIf(Bf3), VIf(Bf2), VOf(Bf3));
+    __hv_sub_f(VIf(Bf3), VIf(Bf2), VOf(Bf2));
+    __hv_var_k_f(VOf(Bf3), -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 0);
+    __hv_mul_f(VIf(Bf2), VIf(Bf3), VOf(Bf3));
+    __hv_var_f(&_c->sVarf_YrcAl, VOf(Bf2));
+    __hv_min_f(VIf(Bf3), VIf(Bf2), VOf(Bf2));
+    __hv_var_f(&_c->sVarf_1pbLN, VOf(Bf3));
+    __hv_max_f(VIf(Bf2), VIf(Bf3), VOf(Bf3));
+    __hv_var_k_f(VOf(Bf2), 1e-37f, 1e-37f, 1e-37f, 1e-37f, 1e-37f, 1e-37f, 1e-37f, 1e-37f, 0);
+    __hv_add_f(VIf(Bf3), VIf(Bf2), VOf(Bf2));
+    __hv_var_k_f(VOf(Bf3), 1e+37f, 1e+37f, 1e+37f, 1e+37f, 1e+37f, 1e+37f, 1e+37f, 1e+37f, 0);
+    __hv_mul_f(VIf(Bf2), VIf(Bf3), VOf(Bf3));
+    __hv_var_k_f(VOf(Bf2), -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 0);
+    __hv_mul_f(VIf(Bf3), VIf(Bf2), VOf(Bf2));
+    __hv_rpole_f(&_c->sRPole_Q5SA1, VIf(Bf1), VIf(Bf2), VOf(Bf2));
+    __hv_var_f(&_c->sVarf_ZTuE8, VOf(Bf1));
+    __hv_min_f(VIf(Bf2), VIf(Bf1), VOf(Bf1));
+    __hv_var_f(&_c->sVarf_9Q4iz, VOf(Bf2));
+    __hv_max_f(VIf(Bf1), VIf(Bf2), VOf(Bf2));
+    __hv_var_f(&_c->sVarf_QHeut, VOf(Bf1));
+    __hv_mul_f(VIf(I9), VIf(I9), VOf(Bf3));
+    __hv_var_f(&_c->sVarf_BWg3y, VOf(Bf4));
+    __hv_min_f(VIf(Bf3), VIf(Bf4), VOf(Bf4));
+    __hv_var_f(&_c->sVarf_yW7Co, VOf(Bf3));
+    __hv_max_f(VIf(Bf4), VIf(Bf3), VOf(Bf3));
+    __hv_div_f(VIf(Bf1), VIf(Bf3), VOf(Bf3));
+    __hv_mul_f(VIf(Bf2), VIf(Bf3), VOf(Bf3));
+    __hv_var_k_f(VOf(Bf2), 512.0f, 512.0f, 512.0f, 512.0f, 512.0f, 512.0f, 512.0f, 512.0f, 0);
+    __hv_mul_f(VIf(Bf3), VIf(Bf2), VOf(Bf2));
+    __hv_var_f(&_c->sVarf_BMuCC, VOf(Bf3));
+    __hv_var_f(&_c->sVarf_1vLiI, VOf(Bf1));
+    __hv_var_f(&_c->sVarf_ZKIZB, VOf(Bf4));
+    __hv_add_f(VIf(Bf2), VIf(Bf4), VOf(Bf4));
+    __hv_var_f(&_c->sVarf_SmDJi, VOf(Bf5));
+    __hv_min_f(VIf(Bf4), VIf(Bf5), VOf(Bf5));
+    __hv_add_f(VIf(Bf1), VIf(Bf5), VOf(Bf5));
+    __hv_var_k_f(VOf(Bf1), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0);
+    __hv_max_f(VIf(Bf5), VIf(Bf1), VOf(Bf1));
+    __hv_cast_fi(VIf(Bf1), VOi(Bi0));
+    __hv_var_k_i(VOi(Bi1), 1, 1, 1, 1, 1, 1, 1, 1, 0);
+    __hv_add_i(VIi(Bi0), VIi(Bi1), VOi(Bi1));
+    __hv_tabread_if(&_c->sTabread_ef8Y2, VIi(Bi1), VOf(Bf5));
+    __hv_var_f(&_c->sVarf_Z1CfH, VOf(Bf4));
+    __hv_add_f(VIf(Bf5), VIf(Bf4), VOf(Bf4));
+    __hv_tabread_if(&_c->sTabread_nnJuj, VIi(Bi0), VOf(Bf5));
+    __hv_sub_f(VIf(Bf4), VIf(Bf5), VOf(Bf4));
+    __hv_add_f(VIf(Bf3), VIf(Bf4), VOf(Bf4));
+    __hv_var_f(&_c->sVarf_CwdRa, VOf(Bf3));
+    __hv_add_f(VIf(Bf3), VIf(Bf1), VOf(Bf3));
+    __hv_floor_f(VIf(Bf1), VOf(Bf1));
+    __hv_sub_f(VIf(Bf3), VIf(Bf1), VOf(Bf1));
+    __hv_var_f(&_c->sVarf_z5YqL, VOf(Bf3));
+    __hv_add_f(VIf(Bf5), VIf(Bf3), VOf(Bf3));
+    __hv_fma_f(VIf(Bf4), VIf(Bf1), VIf(Bf3), VOf(Bf3));
+    __hv_var_f(&_c->sVarf_AMYc1, VOf(Bf1));
+    __hv_var_f(&_c->sVarf_yGh3v, VOf(Bf4));
+    __hv_var_f(&_c->sVarf_ThV6W, VOf(Bf5));
+    __hv_add_f(VIf(Bf2), VIf(Bf5), VOf(Bf5));
+    __hv_var_f(&_c->sVarf_U0HuI, VOf(Bf6));
+    __hv_min_f(VIf(Bf5), VIf(Bf6), VOf(Bf6));
+    __hv_add_f(VIf(Bf4), VIf(Bf6), VOf(Bf6));
+    __hv_var_k_f(VOf(Bf4), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0);
+    __hv_max_f(VIf(Bf6), VIf(Bf4), VOf(Bf4));
+    __hv_cast_fi(VIf(Bf4), VOi(Bi0));
+    __hv_var_k_i(VOi(Bi1), 1, 1, 1, 1, 1, 1, 1, 1, 0);
+    __hv_add_i(VIi(Bi0), VIi(Bi1), VOi(Bi1));
+    __hv_tabread_if(&_c->sTabread_g0gGp, VIi(Bi1), VOf(Bf6));
+    __hv_var_f(&_c->sVarf_rLY2o, VOf(Bf5));
+    __hv_add_f(VIf(Bf6), VIf(Bf5), VOf(Bf5));
+    __hv_tabread_if(&_c->sTabread_joe74, VIi(Bi0), VOf(Bf6));
+    __hv_sub_f(VIf(Bf5), VIf(Bf6), VOf(Bf5));
+    __hv_add_f(VIf(Bf1), VIf(Bf5), VOf(Bf5));
+    __hv_var_f(&_c->sVarf_tTp9Q, VOf(Bf1));
+    __hv_add_f(VIf(Bf1), VIf(Bf4), VOf(Bf1));
+    __hv_floor_f(VIf(Bf4), VOf(Bf4));
+    __hv_sub_f(VIf(Bf1), VIf(Bf4), VOf(Bf4));
+    __hv_var_f(&_c->sVarf_Ip7Ud, VOf(Bf1));
+    __hv_add_f(VIf(Bf6), VIf(Bf1), VOf(Bf1));
+    __hv_fma_f(VIf(Bf5), VIf(Bf4), VIf(Bf1), VOf(Bf1));
+    __hv_mul_f(VIf(Bf1), VIf(Bf1), VOf(Bf1));
+    __hv_var_k_f(VOf(Bf4), 1000.0f, 1000.0f, 1000.0f, 1000.0f, 1000.0f, 1000.0f, 1000.0f, 1000.0f, 0);
+    __hv_var_k_f(VOf(Bf5), 50.0f, 50.0f, 50.0f, 50.0f, 50.0f, 50.0f, 50.0f, 50.0f, 0);
+    __hv_fma_f(VIf(Bf1), VIf(Bf4), VIf(Bf5), VOf(Bf5));
+    __hv_phasor_f(&_c->sPhasor_KqGIr, VIf(Bf5), VOf(Bf5));
+    __hv_var_k_f(VOf(Bf4), 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0);
+    __hv_sub_f(VIf(Bf5), VIf(Bf4), VOf(Bf4));
+    __hv_abs_f(VIf(Bf4), VOf(Bf4));
+    __hv_var_k_f(VOf(Bf5), 0.25f, 0.25f, 0.25f, 0.25f, 0.25f, 0.25f, 0.25f, 0.25f, 0);
+    __hv_sub_f(VIf(Bf4), VIf(Bf5), VOf(Bf5));
+    __hv_var_k_f(VOf(Bf4), 6.28319f, 6.28319f, 6.28319f, 6.28319f, 6.28319f, 6.28319f, 6.28319f, 6.28319f, 0);
+    __hv_mul_f(VIf(Bf5), VIf(Bf4), VOf(Bf4));
+    __hv_mul_f(VIf(Bf4), VIf(Bf4), VOf(Bf5));
+    __hv_mul_f(VIf(Bf4), VIf(Bf5), VOf(Bf1));
+    __hv_mul_f(VIf(Bf1), VIf(Bf5), VOf(Bf5));
+    __hv_var_k_f(VOf(Bf6), 0.00784314f, 0.00784314f, 0.00784314f, 0.00784314f, 0.00784314f, 0.00784314f, 0.00784314f, 0.00784314f, 0);
+    __hv_var_k_f(VOf(Bf7), 0.166667f, 0.166667f, 0.166667f, 0.166667f, 0.166667f, 0.166667f, 0.166667f, 0.166667f, 0);
+    __hv_mul_f(VIf(Bf1), VIf(Bf7), VOf(Bf7));
+    __hv_sub_f(VIf(Bf4), VIf(Bf7), VOf(Bf7));
+    __hv_fma_f(VIf(Bf5), VIf(Bf6), VIf(Bf7), VOf(Bf7));
+    __hv_mul_f(VIf(Bf3), VIf(Bf7), VOf(Bf7));
+    __hv_add_f(VIf(Bf7), VIf(O1), VOf(O1));
+    __hv_add_f(VIf(Bf7), VIf(O0), VOf(O0));
+
+    // save output vars to output buffer
+    __hv_store_f(outputBuffers[0]+n, VIf(O0));
+    __hv_store_f(outputBuffers[1]+n, VIf(O1));
+  }
+
+  Base(_c)->blockStartTimestamp = nextBlock;
+
+  return n4; // return the number of frames processed
+}
+
+int hv_bbb_process_inline(Hv_bbb *c, float *const inputBuffers, float *const outputBuffers, int n4) {
+  hv_assert(!(n4 & HV_N_SIMD_MASK)); // ensure that n4 is a multiple of HV_N_SIMD
+  int i = ctx_getNumInputChannels(Base(c));
+  float **bIn = (float **) hv_alloca(i*sizeof(float *));
+  while (i--) bIn[i] = inputBuffers+(i*n4);
+
+  i = ctx_getNumOutputChannels(Base(c));
+  float **bOut = (float **) hv_alloca(i*sizeof(float *));
+  while (i--) bOut[i] = outputBuffers+(i*n4);
+
+  int n = hv_bbb_process(c, bIn, bOut, n4);
+  return n;
+}
+
+int hv_bbb_process_inline_short(Hv_bbb *c, short *const inputBuffers, short *const outputBuffers, int n4) {
+  hv_assert(!(n4 & HV_N_SIMD_MASK)); // ensure that n4 is a multiple of HV_N_SIMD
+  int numChannels = ctx_getNumInputChannels(Base(c));
+  float *bIn = (float *) hv_alloca(numChannels*n4*sizeof(float));
+  for (int i = 0; i < numChannels; ++i) {
+    for (int j = 0; j < n4; ++j) {
+      bIn[i*n4+j] = ((float) inputBuffers[i+numChannels*j]) * 0.00003051757813f;
+    }
+  }
+
+  numChannels = ctx_getNumOutputChannels(Base(c));
+  float *bOut = (float *) hv_alloca(numChannels*n4*sizeof(float));
+
+  int n = hv_bbb_process_inline(c, bIn, bOut, n4);
+
+  for (int i = 0; i < numChannels; ++i) {
+    for (int j = 0; j < n4; ++j) {
+      outputBuffers[i+numChannels*j] = (short) (bOut[i*n4+j] * 32767.0f);
+    }
+  }
+
+  return n;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/projects/heavy/envelopeTrigger/HvContext_bbb.h	Thu Nov 12 14:59:46 2015 +0000
@@ -0,0 +1,121 @@
+
+/**
+ * Copyright (c) 2014,2015 Enzien Audio, Ltd.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, and/or
+ * sublicense copies of the Software, strictly on a non-commercial basis,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * DO NOT MODIFY. THIS CODE IS MACHINE GENERATED BY THE SECTION6 HEAVY COMPILER.
+ */
+
+#ifndef _HEAVYCONTEXT_BBB_H_
+#define _HEAVYCONTEXT_BBB_H_
+
+#include "HvBase.h"
+
+#define Context(_x) ((Hv_bbb *) (_x))
+
+// object includes
+#include "ControlSystem.h"
+#include "SignalVar.h"
+#include "HvTable.h"
+#include "ControlSlice.h"
+#include "SignalTabread.h"
+#include "HeavyMath.h"
+#include "ControlBinop.h"
+#include "ControlVar.h"
+#include "SignalDel1.h"
+#include "SignalBiquad.h"
+#include "SignalPhasor.h"
+#include "ControlUnop.h"
+#include "SignalRPole.h"
+
+typedef struct Hv_bbb {
+  HvBase base;
+
+  // objects
+  SignalVarf sVarf_DIQHM;
+  SignalVarf sVarf_EIzJc;
+  SignalVarf sVarf_J0BAW;
+  SignalRPole sRPole_vtJYw;
+  SignalVarf sVarf_haFXq;
+  SignalDel1 sDel1_8dkfF;
+  SignalVarf sVarf_4RU63;
+  SignalVarf sVarf_5BIjv;
+  SignalVarf sVarf_82QyC;
+  SignalBiquad_k sBiquad_k_8Keaz;
+  SignalVarf sVarf_2muG8;
+  SignalVarf sVarf_YrcAl;
+  SignalVarf sVarf_1pbLN;
+  SignalRPole sRPole_Q5SA1;
+  SignalVarf sVarf_ZTuE8;
+  SignalVarf sVarf_9Q4iz;
+  SignalVarf sVarf_QHeut;
+  SignalVarf sVarf_BWg3y;
+  SignalVarf sVarf_yW7Co;
+  SignalVarf sVarf_BMuCC;
+  SignalVarf sVarf_1vLiI;
+  SignalVarf sVarf_ZKIZB;
+  SignalVarf sVarf_SmDJi;
+  SignalTabread sTabread_ef8Y2;
+  SignalVarf sVarf_Z1CfH;
+  SignalTabread sTabread_nnJuj;
+  SignalVarf sVarf_CwdRa;
+  SignalVarf sVarf_z5YqL;
+  SignalVarf sVarf_AMYc1;
+  SignalVarf sVarf_yGh3v;
+  SignalVarf sVarf_ThV6W;
+  SignalVarf sVarf_U0HuI;
+  SignalTabread sTabread_g0gGp;
+  SignalVarf sVarf_rLY2o;
+  SignalTabread sTabread_joe74;
+  SignalVarf sVarf_tTp9Q;
+  SignalVarf sVarf_Ip7Ud;
+  SignalPhasor sPhasor_KqGIr;
+  HvTable hTable_Pcegq;
+  ControlVar cVar_rLv9w;
+  ControlVar cVar_rQhd0;
+  ControlSlice cSlice_LzkmO;
+  ControlBinop cBinop_ER1x8;
+  ControlSlice cSlice_HqIeY;
+  ControlVar cVar_BTo3t;
+  ControlVar cVar_ZzlGn;
+  ControlBinop cBinop_HqDsI;
+  ControlBinop cBinop_oOwFV;
+  ControlBinop cBinop_P09tj;
+  ControlVar cVar_NnTc2;
+  ControlBinop cBinop_f8PBr;
+  ControlBinop cBinop_ITJR9;
+  ControlBinop cBinop_cxljx;
+  ControlBinop cBinop_0UlVT;
+  ControlBinop cBinop_MJQIs;
+  ControlBinop cBinop_a2rE6;
+  ControlBinop cBinop_govla;
+  ControlSlice cSlice_oxbrV;
+  ControlBinop cBinop_rzeQ2;
+  ControlSlice cSlice_yZctV;
+  ControlSlice cSlice_HCNcS;
+  ControlVar cVar_ItOCU;
+  ControlSlice cSlice_Nx0UC;
+  ControlVar cVar_VE9tg;
+  ControlBinop cBinop_RE1w0;
+  ControlSlice cSlice_Pkd46;
+} Hv_bbb;
+
+#endif // _HEAVYCONTEXT_BBB_H_
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/projects/heavy/envelopeTrigger/HvMessage.c	Thu Nov 12 14:59:46 2015 +0000
@@ -0,0 +1,335 @@
+/**
+ * Copyright (c) 2014, 2015, Enzien Audio Ltd.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "HvMessage.h"
+
+HvMessage *msg_init(HvMessage *m, hv_size_t numElements, hv_uint32_t timestamp) {
+  m->timestamp = timestamp;
+  m->numElements = (hv_uint16_t) numElements;
+  m->numBytes = (hv_uint16_t) msg_getByteSize(numElements);
+  return m;
+}
+
+HvMessage *msg_initWithFloat(HvMessage *m, hv_uint32_t timestamp, float f) {
+  m->timestamp = timestamp;
+  m->numElements = 1;
+  m->numBytes = sizeof(HvMessage);
+  msg_setFloat(m, 0, f);
+  return m;
+}
+
+HvMessage *msg_initWithBang(HvMessage *m, hv_uint32_t timestamp) {
+  m->timestamp = timestamp;
+  m->numElements = 1;
+  m->numBytes = sizeof(HvMessage);
+  msg_setBang(m, 0);
+  return m;
+}
+
+HvMessage *msg_initWithSymbol(HvMessage *m, hv_uint32_t timestamp, char *s) {
+  m->timestamp = timestamp;
+  m->numElements = 1;
+  m->numBytes = sizeof(HvMessage);
+  msg_setSymbol(m, 0, s);
+  return m;
+}
+
+HvMessage *msg_initWithHash(HvMessage *m, hv_uint32_t timestamp, hv_uint32_t h) {
+  m->timestamp = timestamp;
+  m->numElements = 1;
+  m->numBytes = sizeof(HvMessage);
+  msg_setHash(m, 0, h);
+  return m;
+}
+
+HvMessage *msg_initV(HvMessage *const m, const hv_uint32_t timestamp, const char *format, ...) {
+  va_list ap;
+  va_start(ap, format);
+
+  const int numElem = (int) hv_strlen(format);
+  msg_init(m, numElem, timestamp);
+  for (int i = 0; i < numElem; i++) {
+    switch (format[i]) {
+      case 'b': msg_setBang(m,i); break;
+      case 'f': msg_setFloat(m, i, (float) va_arg(ap, double)); break;
+      case 's': msg_setSymbol(m, i, (char *) va_arg(ap, char *)); break;
+      case 'h': // hash not supported
+      default: break;
+    }
+  }
+  va_end(ap);
+
+  return m;
+}
+
+hv_size_t msg_getNumHeapBytes(const HvMessage *m) {
+  // get the size of all symbol elements
+  hv_size_t rsizeofsym = 0;
+  for (int i = 0; i < msg_getNumElements(m); ++i) {
+    if (msg_isSymbol(m,i)) {
+      rsizeofsym += (hv_size_t) hv_strlen(msg_getSymbol(m,i)) + 1; // +1 to allow for trailing '\0'
+    }
+  }
+
+  // the total byte size on the heap
+  return (msg_getByteSize(msg_getNumElements(m)) + rsizeofsym);
+}
+
+void msg_copyToBuffer(const HvMessage *m, char *buffer, hv_size_t len) {
+  HvMessage *r = (HvMessage *) buffer;
+
+  // assert that the message is not already larger than the length of the buffer
+  hv_assert(msg_getNumBytes(m) <= len);
+
+  // copy the basic message to the buffer
+  hv_memcpy(r, m, msg_getNumBytes(m));
+
+  hv_size_t len_r = msg_getNumBytes(m);
+
+  char *p = buffer + msg_getByteSize(msg_getNumElements(m)); // points to the end of the base message
+  for (int i = 0; i < msg_getNumElements(m); ++i) {
+    if (msg_isSymbol(m,i)) {
+      const hv_size_t symLen = (hv_size_t) hv_strlen(msg_getSymbol(m,i)) + 1; // include the trailing null char
+      hv_assert(len_r + symLen <= len); // stay safe!
+      hv_strncpy(p, msg_getSymbol(m,i), symLen);
+      msg_setSymbol(r, i, p);
+      p += symLen;
+      len_r += symLen;
+    }
+  }
+
+  r->numBytes = (hv_uint16_t) len_r; // update the message size in memory
+}
+
+// the message is serialised such that all symbol elements are placed in order at the end of the buffer
+HvMessage *msg_copy(const HvMessage *m) {
+  const hv_size_t heapSize = msg_getNumHeapBytes(m);
+  char *r = (char *) hv_malloc(heapSize);
+  msg_copyToBuffer(m, r, heapSize);
+  return (HvMessage *) r;
+}
+
+void msg_free(HvMessage *m) {
+  hv_free(m); // because heap messages are serialised in memory, a simple call to free releases the message
+}
+
+bool msg_hasFormat(const HvMessage *m, const char *fmt) {
+  if (fmt == NULL) return false;
+  if (msg_getNumElements(m) != hv_strlen(fmt)) return false;
+  for (int i = 0; i < msg_getNumElements(m); i++) {
+    switch (fmt[i]) {
+      case 'b': if (!msg_isBang(m, i)) return false; break;
+      case 'f': if (!msg_isFloat(m, i)) return false; break;
+      case 's': if (!msg_isSymbol(m, i)) return false; break;
+      case 'h': if (!msg_isHash(m, i)) return false; break;
+      default: return false;
+    }
+  }
+  return true;
+}
+
+bool msg_compareSymbol(const HvMessage *m, int i, const char *s) {
+  switch (msg_getType(m,i)) {
+    case SYMBOL: return !hv_strcmp(msg_getSymbol(m, i), s);
+    case HASH: return (msg_getHash(m,i) == msg_symbolToHash(s));
+    default: return false;
+  }
+}
+
+bool msg_equalsElement(const HvMessage *m, int i_m, const HvMessage *n, int i_n) {
+  if (i_m < msg_getNumElements(m) && i_n < msg_getNumElements(n)) {
+    if (msg_getType(m, i_m) == msg_getType(n, i_n)) {
+      switch (msg_getType(m, i_m)) {
+        case BANG: return true;
+        case FLOAT: return (msg_getFloat(m, i_m) == msg_getFloat(n, i_n));
+        case SYMBOL: return msg_compareSymbol(m, i_m, msg_getSymbol(n, i_n));
+        case HASH: return msg_getHash(m,i_m) == msg_getHash(n,i_n);
+        default: break;
+      }
+    }
+  }
+  return false;
+}
+
+void msg_setElementToFrom(HvMessage *n, int i_n, const HvMessage *const m, int i_m) {
+  switch (msg_getType(m, i_m)) {
+    case BANG: msg_setBang(n, i_n); break;
+    case FLOAT: msg_setFloat(n, i_n, msg_getFloat(m, i_m)); break;
+    case SYMBOL: msg_setSymbol(n, i_n, msg_getSymbol(m, i_m)); break;
+    case HASH: msg_setHash(n, i_n, msg_getHash(m, i_m));
+    default: break;
+  }
+}
+
+hv_uint32_t msg_symbolToHash(const char *s) {
+  // this hash is based MurmurHash2
+  // http://en.wikipedia.org/wiki/MurmurHash
+  // https://sites.google.com/site/murmurhash/
+  static const unsigned int n = 0x5bd1e995;
+  static const int r = 24;
+
+  int len = (int) hv_strlen(s);
+  hv_uint32_t x = (hv_uint32_t) (len); // seed (0) ^ len
+
+  while (len >= 4) {
+    hv_uint32_t k = *((hv_uint32_t *)s);
+    k *= n;
+    k ^= k >> r;
+    k *= n;
+    x *= n;
+    x ^= k;
+    s += 4; len -= 4;
+  }
+
+  switch(len) {
+    case 3: x ^= s[2] << 16;
+    case 2: x ^= s[1] << 8;
+    case 1: x ^= s[0]; x *= n;
+    default: break;
+  }
+
+  x ^= x >> 13;
+  x *= n;
+  x ^= x >> 15;
+
+  return x;
+}
+
+hv_uint32_t msg_getHash(const HvMessage *const m, int i) {
+  hv_assert(i < msg_getNumElements(m)); // invalid index
+  switch (msg_getType(m,i)) {
+    case BANG: return 0xFFFFFFFF;
+    case FLOAT: {
+      float f = msg_getFloat(m,i);
+      return *((hv_uint32_t *) &f);
+    }
+    case SYMBOL: return msg_symbolToHash(msg_getSymbol(m,i));
+    case HASH: return (&(m->elem)+i)->data.h;
+    default: return 0;
+  }
+}
+
+char *msg_toString(const HvMessage *m) {
+  hv_assert(msg_getNumElements(m) > 0);
+  int *len = (int *) hv_alloca(msg_getNumElements(m)*sizeof(int));
+  int size = 0; // the total length of our final buffer
+
+  // loop through every element in our list of atoms
+  // first loop figures out how long our buffer should be
+  for (int i = 0; i < msg_getNumElements(m); i++) {
+    // length of our string is each atom plus a space, or \0 on the end
+    switch (msg_getType(m, i)) {
+      case BANG: len[i] = hv_snprintf(NULL, 0, "%s", "bang") + 1; break;
+      case FLOAT: len[i] = hv_snprintf(NULL, 0, "%g", msg_getFloat(m, i)) + 1; break;
+      case SYMBOL: len[i] = hv_snprintf(NULL, 0, "%s", msg_getSymbol(m, i)) + 1; break;
+      case HASH: len[i] = hv_snprintf(NULL, 0, "0x%X", msg_getHash(m, i)) + 1; break;
+      default: break;
+    }
+    size += len[i];
+  }
+
+  hv_assert(size > 0);
+
+  // now we do the piecewise concatenation into our final string
+  // the final buffer we will pass back after concatenating all strings - user should free it
+  char *finalString = (char *) hv_malloc(size*sizeof(char));
+  int pos = 0;
+  for (int i = 0; i < msg_getNumElements(m); i++) {
+    // put a string representation of each atom into the final string
+    switch (msg_getType(m, i)) {
+      case BANG: hv_snprintf(finalString+pos, len[i], "%s", "bang"); break;
+      case FLOAT: hv_snprintf(finalString+pos, len[i], "%g", msg_getFloat(m, i)); break;
+      case SYMBOL: hv_snprintf(finalString+pos, len[i], "%s", msg_getSymbol(m, i)); break;
+      case HASH: hv_snprintf(finalString+pos, len[i], "0x%X", msg_getHash(m, i)); break;
+      default: break;
+    }
+    pos += len[i];
+    finalString[pos-1] = 32; // ASCII space
+  }
+  finalString[size-1] = '\0'; // ensure that the string is null terminated
+  return finalString;
+}
+
+/*
+ * TODO(mhroth): unnecessary for now
+bool msg_resolveDollarArguments(HvMessage *m, HvMessage *n, int z, char *buf, hv_size_t len, const char *args, ...) {
+  va_list ap;
+  va_start(ap, args);
+
+  hv_memset(buf, 0, len); // clear the buffer
+  hv_size_t j = 0; // position in buffer
+  const hv_size_t numArgs = hv_strlen(args); // the number of arguments
+
+  // if there is only one argument then the result has the chance of being a number, otherwise no
+  bool isNumber = (numArgs == 1);
+
+  for (hv_size_t i = 0; i < numArgs; ++i) {
+    switch (args[i]) {
+      case 'i': { // a message index
+        const int index = (int) va_arg(ap, int);
+        if (index < 0) {
+          // $0 always resolve to "0"
+          const hv_size_t x = 1;
+          if (x < len-j) { // always < in order to allow for trailing \0
+            j += snprintf(buf+j, len-j, "0");
+          }
+        } else {
+          switch (msg_getType(m, index)) {
+            default:
+            case BANG: break; // this case should never happen
+            case FLOAT: {
+              const hv_size_t x = snprintf(NULL, 0, "%g", msg_getFloat(m,index));
+              if (x < len-j) { // ensure that the buffer is big enough
+                j += snprintf(buf+j, len-j, "%g", msg_getFloat(m,index));
+              }
+              break;
+            }
+            case SYMBOL: {
+              const hv_size_t x = snprintf(NULL, 0, "%s", msg_getSymbol(m,index));
+              if (x < len-j) {
+                j += snprintf(buf+j, len-j, "%s", msg_getSymbol(m,index));
+                isNumber = false;
+              }
+              break;
+            }
+          }
+        }
+        break;
+      }
+      case 's': { // a string
+        const char *s = (char *) va_arg(ap, char *);
+        const hv_size_t x = snprintf(NULL, 0, "%s", s);
+        if (x <= len-j) {
+          j += snprintf(buf+j, len-j, "%s", s);
+          isNumber = false;
+        }
+        break;
+      }
+      default: break;
+    }
+  }
+
+  if (isNumber) {
+    msg_setFloat(n,z,(float) atof(buf));
+  } else {
+    msg_setSymbol(n,z,buf);
+  }
+
+  va_end(ap);
+
+  return !isNumber;
+}
+*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/projects/heavy/envelopeTrigger/HvMessage.h	Thu Nov 12 14:59:46 2015 +0000
@@ -0,0 +1,188 @@
+/**
+ * Copyright (c) 2014, 2015, Enzien Audio Ltd.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _HEAVY_MESSAGE_H_
+#define _HEAVY_MESSAGE_H_
+
+#include "Utils.h"
+
+typedef enum ElementType {
+  BANG,
+  FLOAT,
+  SYMBOL,
+  HASH
+} ElementType;
+
+typedef struct Element {
+  ElementType type;
+  union {
+    float f; // float
+    char *s; // symbol
+    hv_uint32_t h; // hash
+  } data;
+} Element;
+
+typedef struct HvMessage {
+  hv_uint32_t timestamp; // the sample at which this message should be processed
+  hv_uint16_t numElements;
+  hv_uint16_t numBytes; // the number of bytes that this message occupies in memory
+  Element elem;
+} HvMessage;
+
+#define HV_MESSAGE_ON_STACK(_x) (HvMessage *) hv_alloca(msg_getByteSize(_x))
+
+/** Returns the total length in bytes of this message for a given number of elements. */
+static inline hv_size_t msg_getByteSize(hv_size_t numElements) {
+  hv_assert(numElements > 0);
+  return sizeof(HvMessage) + ((numElements-1) * sizeof(Element));
+}
+
+HvMessage *msg_copy(const HvMessage *m);
+
+/** Returns the number of bytes that this message would occupy on the heap. */
+hv_size_t msg_getNumHeapBytes(const HvMessage *m);
+
+/** Copies the message into the given buffer. The buffer must be at least as large as msg_getNumHeapBytes(). */
+void msg_copyToBuffer(const HvMessage *m, char *buffer, hv_size_t len);
+
+void msg_setElementToFrom(HvMessage *n, int indexN, const HvMessage *const m, int indexM);
+
+/** Frees a message on the heap. Does nothing if argument is NULL. */
+void msg_free(HvMessage *m);
+
+HvMessage *msg_init(HvMessage *m, hv_size_t numElements, hv_uint32_t timestamp);
+
+HvMessage *msg_initWithFloat(HvMessage *m, hv_uint32_t timestamp, float f);
+
+HvMessage *msg_initWithBang(HvMessage *m, hv_uint32_t timestamp);
+
+HvMessage *msg_initWithSymbol(HvMessage *m, hv_uint32_t timestamp, char *s);
+
+HvMessage *msg_initWithHash(HvMessage *m, hv_uint32_t timestamp, hv_uint32_t h);
+
+HvMessage *msg_initV(HvMessage *const m, const hv_uint32_t timestamp, const char *format, ...);
+
+static inline hv_uint32_t msg_getTimestamp(const HvMessage *m) {
+  return m->timestamp;
+}
+
+static inline void msg_setTimestamp(HvMessage *m, hv_uint32_t timestamp) {
+  m->timestamp = timestamp;
+}
+
+static inline int msg_getNumElements(const HvMessage *m) {
+  return (int) m->numElements;
+}
+
+/** Returns the number of bytes this message in memory. */
+static inline hv_size_t msg_getNumBytes(const HvMessage *m) {
+  return m->numBytes;
+}
+
+static inline ElementType msg_getType(const HvMessage *m, int index) {
+  hv_assert(index < msg_getNumElements(m)); // invalid index
+  return (&(m->elem)+index)->type;
+}
+
+static inline void msg_setBang(HvMessage *m, int index) {
+  hv_assert(index < msg_getNumElements(m)); // invalid index
+  (&(m->elem)+index)->type = BANG;
+  (&(m->elem)+index)->data.s = NULL;
+}
+
+static inline bool msg_isBang(const HvMessage *m, int index) {
+  return (index < msg_getNumElements(m)) ? (msg_getType(m,index) == BANG) : false;
+}
+
+static inline void msg_setFloat(HvMessage *m, int index, float f) {
+  hv_assert(index < msg_getNumElements(m)); // invalid index
+  (&(m->elem)+index)->type = FLOAT;
+  (&(m->elem)+index)->data.f = f;
+}
+
+static inline float msg_getFloat(const HvMessage *const m, int index) {
+  hv_assert(index < msg_getNumElements(m)); // invalid index
+  return (&(m->elem)+index)->data.f;
+}
+
+static inline bool msg_isFloat(const HvMessage *const m, int index) {
+  return (index < msg_getNumElements(m)) ? (msg_getType(m,index) == FLOAT) : false;
+}
+
+static inline void msg_setHash(HvMessage *m, int index, hv_uint32_t h) {
+  hv_assert(index < msg_getNumElements(m)); // invalid index
+  (&(m->elem)+index)->type = HASH;
+  (&(m->elem)+index)->data.h = h;
+}
+
+static inline bool msg_isHash(const HvMessage *m, int index) {
+  return (index < msg_getNumElements(m)) ? (msg_getType(m, index) == HASH) : false;
+}
+
+/** Returns true if the element is a hash or symbol. False otherwise. */
+static inline bool msg_isHashLike(const HvMessage *m, int index) {
+  return (index < msg_getNumElements(m)) ? ((msg_getType(m, index) == HASH) || (msg_getType(m, index) == SYMBOL)) : false;
+}
+
+/** Returns a 32-bit hash of the given string. */
+hv_uint32_t msg_symbolToHash(const char *s);
+
+/** Returns a 32-bit hash of the given element. */
+hv_uint32_t msg_getHash(const HvMessage *const m, int i);
+
+static inline void msg_setSymbol(HvMessage *m, int index, char *s) {
+  hv_assert(index < msg_getNumElements(m)); // invalid index
+  (&(m->elem)+index)->type = SYMBOL;
+  (&(m->elem)+index)->data.s = s;
+}
+
+static inline char *msg_getSymbol(const HvMessage *m, int index) {
+  hv_assert(index < msg_getNumElements(m)); // invalid index
+  return (&(m->elem)+index)->data.s;
+}
+
+static inline bool msg_isSymbol(const HvMessage *m, int index) {
+  return (index < msg_getNumElements(m)) ? (msg_getType(m, index) == SYMBOL) : false;
+}
+
+bool msg_compareSymbol(const HvMessage *m, int i, const char *s);
+
+/** Returns 1 if the element i_m of message m is equal to element i_n of message n. */
+bool msg_equalsElement(const HvMessage *m, int i_m, const HvMessage *n, int i_n);
+
+bool msg_hasFormat(const HvMessage *m, const char *fmt);
+
+/**
+ * Create a string representation of the message. Suitable for use by the print object.
+ * The resulting string must be freed by the caller.
+ */
+char *msg_toString(const HvMessage *msg);
+
+/**
+ * Resolves any number of dollar arguments and generates a string based on the arguments.
+ * @param m  The message from which to take values
+ * @param n  The message to fill in
+ * @param z  The element index to resolve
+ * @param buf  The scratch (i.e. resolution) buffer
+ * @param len  The length of the scratch buffer
+ * @param args  A string of 'i' and 's' chars indicating the type of the arguments, either indicies or strings
+ * @param varargs  The components to resolve, either dollar indicies or strings.
+ * If the index is negative, the graph id is used
+ * @return  true if the resolution buffer is needed, false otherwise.
+ */
+// bool msg_resolveDollarArguments(HvMessage *m, HvMessage *n, int z, char *buf, hv_size_t len, const char *args, ...);
+
+#endif // _HEAVY_MESSAGE_H_
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/projects/heavy/envelopeTrigger/HvTable.c	Thu Nov 12 14:59:46 2015 +0000
@@ -0,0 +1,101 @@
+/**
+ * Copyright (c) 2014, 2015, Enzien Audio Ltd.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "HvTable.h"
+
+hv_size_t hTable_init(HvTable *o, int length) {
+  o->length = length;
+  // true size of the table is always an integer multple of HV_N_SIMD
+  o->size = (length + HV_N_SIMD_MASK) & ~HV_N_SIMD_MASK;
+  // add an extra length for mirroring
+  o->allocated = o->size + HV_N_SIMD;
+  o->head = 0;
+  hv_size_t numBytes = o->allocated * sizeof(float);
+  o->buffer = (float *) hv_malloc(numBytes);
+  hv_memset(o->buffer, numBytes);
+  return numBytes;
+}
+
+hv_size_t hTable_initWithData(HvTable *o, int length, const float *const data) {
+  o->length = length;
+  o->size = (length + HV_N_SIMD_MASK) & ~HV_N_SIMD_MASK;
+  o->allocated = o->size + HV_N_SIMD;
+  o->head = 0;
+  hv_size_t numBytes = o->size * sizeof(float);
+  o->buffer = (float *) hv_malloc(numBytes);
+  hv_memset(o->buffer, numBytes);
+  hv_memcpy(o->buffer, data, length*sizeof(float));
+  return numBytes;
+}
+
+hv_size_t hTable_initWithFinalData(HvTable *o, int length, float *data) {
+  o->length = length;
+  o->size = length;
+  o->allocated = length;
+  o->buffer = data;
+  o->head = 0;
+  return 0;
+}
+
+void hTable_free(HvTable *o) {
+  hv_free(o->buffer);
+}
+
+int hTable_resize(HvTable *o, hv_uint32_t newLength) {
+  // TODO(mhroth): update context with memory allocated by table
+  // NOTE(mhroth): mirrored bytes are not necessarily carried over
+  const hv_uint32_t oldBytes = (hv_uint32_t) (o->size * sizeof(float));
+  const hv_uint32_t newSize = (newLength + HV_N_SIMD_MASK) & ~HV_N_SIMD_MASK;
+  const hv_uint32_t newAllocated = newSize + HV_N_SIMD;
+  const hv_uint32_t newBytes = (hv_uint32_t) (newAllocated * sizeof(float));
+  float *b = (float *) hv_realloc(o->buffer, newBytes);
+  hv_assert(b != NULL); // error while reallocing!
+  if (newSize > o->size) hv_clear_buffer(b+o->size, newAllocated-o->size); // clear new parts of the buffer
+  if (b != o->buffer) {
+    // the buffer has been reallocated, ensure that it is on a 32-byte boundary
+    if ((((uintptr_t) (const void *) b) & 0x10) == 0) {
+      o->buffer = b;
+    } else {
+      float *c = (float *) hv_malloc(newBytes);
+      hv_assert(c != NULL);
+      hv_clear_buffer(c, newLength);
+      const hv_size_t min = hv_min_ui(o->size, newLength);
+      hv_memcpy(c, b, min * sizeof(float));
+      hv_free(b);
+      o->buffer = c;
+    }
+  }
+  o->length = newLength;
+  o->size = newSize;
+  o->allocated = newAllocated;
+  return (int) (newBytes - oldBytes);
+}
+
+void hTable_onMessage(HvBase *_c, HvTable *o, int letIn, const HvMessage *const m,
+    void (*sendMessage)(HvBase *, int, const HvMessage *const)) {
+  if (msg_compareSymbol(m,0,"resize") && msg_isFloat(m,1) && msg_getFloat(m,1) >= 0.0f) {
+    hTable_resize(o, (int) hv_ceil_f(msg_getFloat(m,1))); // apply ceil to ensure that tables always have enough space
+
+    // send out the new size of the table
+    HvMessage *n = HV_MESSAGE_ON_STACK(1);
+    msg_initWithFloat(n, msg_getTimestamp(m), (float) hTable_getSize(o));
+    sendMessage(_c, 0, n);
+  }
+
+  else if (msg_compareSymbol(m,0,"mirror")) {
+    hv_memcpy(o->buffer+o->size, o->buffer, HV_N_SIMD*sizeof(float));
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/projects/heavy/envelopeTrigger/HvTable.h	Thu Nov 12 14:59:46 2015 +0000
@@ -0,0 +1,81 @@
+/**
+ * Copyright (c) 2014, 2015, Enzien Audio Ltd.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _HEAVY_TABLE_H_
+#define _HEAVY_TABLE_H_
+
+#include "HvBase.h"
+#include "HvMessage.h"
+#include "Utils.h"
+
+typedef struct HvTable {
+  float *buffer;
+  // the number of values that the table is requested to have
+  hv_uint32_t length;
+
+  // the number of usable values that the table actually has
+  // this is always an even multiple of HV_N_SIMD
+  hv_uint32_t size;
+
+  // Note that the true size of the table is (size + HV_N_SIMD),
+  // with the trailing values used by the system, e.g. to create a circular
+  // buffer
+  hv_uint32_t allocated;
+
+  hv_uint32_t head; // the most recently written point
+} HvTable;
+
+hv_size_t hTable_init(HvTable *o, int length);
+
+hv_size_t hTable_initWithData(HvTable *o, int length, const float *const data);
+
+hv_size_t hTable_initWithFinalData(HvTable *o, int length, float *data);
+
+void hTable_free(HvTable *o);
+
+int hTable_resize(HvTable *o, hv_uint32_t newLength);
+
+void hTable_onMessage(HvBase *_c, HvTable *o, int letIn, const HvMessage *const m,
+    void (*sendMessage)(HvBase *, int, const HvMessage *const));
+
+static inline float *hTable_getBuffer(HvTable *o) {
+  return o->buffer;
+}
+
+// the user-requested length of the table (number of floats)
+static inline hv_uint32_t hTable_getLength(HvTable *o) {
+  return o->length;
+}
+
+// the usable length of the table (an even multiple of HV_N_SIMD)
+static inline hv_uint32_t hTable_getSize(HvTable *o) {
+  return o->size;
+}
+
+// the number of floats allocated to this table (usually size + HV_N_SIMD)
+static inline hv_uint32_t hTable_getAllocated(HvTable *o) {
+  return o->allocated;
+}
+
+static inline hv_uint32_t hTable_getHead(HvTable *o) {
+  return o->head;
+}
+
+static inline void hTable_setHead(HvTable *o, hv_uint32_t head) {
+  o->head = head;
+}
+
+#endif // _HEAVY_TABLE_H_
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/projects/heavy/envelopeTrigger/MessagePool.c	Thu Nov 12 14:59:46 2015 +0000
@@ -0,0 +1,141 @@
+/**
+ * Copyright (c) 2014, 2015, Enzien Audio Ltd.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "MessagePool.h"
+#include "HvMessage.h"
+#include "Utils.h"
+
+// the number of bytes reserved at a time from the pool
+#define MP_BLOCK_SIZE_BYTES 512
+
+#if HV_APPLE
+#pragma mark - MessageList
+#endif
+
+typedef struct MessageListNode {
+  char *p;
+  struct MessageListNode *next;
+} MessageListNode;
+
+static inline bool ml_hasAvailable(MessagePoolList *ml) {
+  return (ml->head != NULL);
+}
+
+static char *ml_pop(MessagePoolList *ml) {
+  MessageListNode *n = ml->head;
+  ml->head = n->next;
+  n->next = ml->pool;
+  ml->pool = n;
+  char *const p = n->p;
+  n->p = NULL; // set to NULL to make it clear that this node does not have a valid buffer
+  return p;
+}
+
+/** Push a MessageListNode with the given pointer onto the head of the queue. */
+static void ml_push(MessagePoolList *ml, void *p) {
+  MessageListNode *n = NULL;
+  if (ml->pool != NULL) {
+    // take an empty MessageListNode from the pool
+    n = ml->pool;
+    ml->pool = n->next;
+  } else {
+    // a MessageListNode is not available, allocate one
+    n = (MessageListNode *) hv_malloc(sizeof(MessageListNode));
+  }
+  n->p = (char *) p;
+  n->next = ml->head;
+  ml->head = n; // push to the front of the queue
+}
+
+static void ml_free(MessagePoolList *ml) {
+  if (ml != NULL) {
+    while (ml_hasAvailable(ml)) {
+      ml_pop(ml);
+    }
+    while (ml->pool != NULL) {
+      MessageListNode *n = ml->pool;
+      ml->pool = n->next;
+      hv_free(n);
+    }
+  }
+}
+
+#if HV_APPLE
+#pragma mark - MessagePool
+#endif
+
+static hv_size_t mp_messagelistIndexForSize(hv_size_t byteSize) {
+  return (hv_size_t) hv_max_i((hv_min_max_log2((hv_uint32_t) byteSize) - 5), 0);
+}
+
+hv_size_t mp_init(MessagePool *mp, hv_size_t numKB) {
+  mp->bufferSize = numKB * 1024;
+  mp->buffer = (char *) hv_malloc(mp->bufferSize);
+  mp->bufferIndex = 0;
+
+  // initialise all message lists
+  for (int i = 0; i < MP_NUM_MESSAGE_LISTS; i++) {
+    mp->lists[i].head = NULL;
+    mp->lists[i].pool = NULL;
+  }
+
+  return mp->bufferSize;
+}
+
+void mp_free(MessagePool *mp) {
+  hv_free(mp->buffer);
+  for (int i = 0; i < MP_NUM_MESSAGE_LISTS; i++) {
+    ml_free(&mp->lists[i]);
+  }
+}
+
+void mp_freeMessage(MessagePool *mp, HvMessage *m) {
+  const hv_size_t b = msg_getNumBytes(m); // the number of bytes that a message occupies in memory
+  const hv_size_t i = mp_messagelistIndexForSize(b); // the MessagePoolList index in the pool
+  MessagePoolList *ml = &mp->lists[i];
+  const hv_size_t chunkSize = 32 << i;
+  hv_memset(m, chunkSize); // clear the chunk, just in case
+  ml_push(ml, m);
+}
+
+HvMessage *mp_addMessage(MessagePool *mp, const HvMessage *m) {
+  const hv_size_t b = msg_getNumHeapBytes(m);
+  // determine the message list index to allocate data from based on the msg size
+  // smallest chunk size is 32 bytes
+  const hv_size_t i = mp_messagelistIndexForSize(b);
+
+  assert(i < MP_NUM_MESSAGE_LISTS); // how many chunk sizes do we want to support? 32, 64, 128, 256 at the moment
+  MessagePoolList *ml = &mp->lists[i];
+  const hv_size_t chunkSize = 32 << i;
+
+  if (ml_hasAvailable(ml)) {
+    char *buf = ml_pop(ml);
+    msg_copyToBuffer(m, buf, chunkSize);
+    return (HvMessage *) buf;
+  } else {
+    // if no appropriately sized buffer is immediately available, increase the size of the used buffer
+    const hv_size_t newIndex = mp->bufferIndex + MP_BLOCK_SIZE_BYTES;
+    hv_assert(newIndex <= mp->bufferSize); // have we have exceeded the buffer size?
+
+    for (hv_size_t i = mp->bufferIndex; i < newIndex; i += chunkSize) {
+      ml_push(ml, mp->buffer + i); // push new nodes onto the list with chunk pointers
+    }
+    mp->bufferIndex = newIndex;
+    char *buf = ml_pop(ml);
+    msg_copyToBuffer(m, buf, chunkSize);
+    return (HvMessage *) buf;
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/projects/heavy/envelopeTrigger/MessagePool.h	Thu Nov 12 14:59:46 2015 +0000
@@ -0,0 +1,61 @@
+/**
+ * Copyright (c) 2014, 2015, Enzien Audio Ltd.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _MESSAGE_POOL_H_
+#define _MESSAGE_POOL_H_
+
+#include "Utils.h"
+
+struct HvMessage;
+
+#define MP_NUM_MESSAGE_LISTS 4
+
+typedef struct MessagePoolList {
+  struct MessageListNode *head; // list of currently available blocks
+  struct MessageListNode *pool; // list of currently used blocks
+} MessagePoolList;
+
+typedef struct MessagePool {
+  char *buffer; // the buffer of all messages
+  hv_size_t bufferSize; // in bytes
+  hv_size_t bufferIndex; // the number of total reserved bytes
+
+  MessagePoolList lists[MP_NUM_MESSAGE_LISTS];
+} MessagePool;
+
+/**
+ * The MessagePool is a basic memory management system. It reserves a large block of memory at initialisation
+ * and proceeds to divide this block into smaller chunks (usually 512 bytes) as they are needed. These chunks are
+ * further divided into 32, 64, 128, or 256 sections. Each of these sections is managed by a MessagePoolList (MPL).
+ * An MPL is a linked-list data structure which is initialised such that its own pool of listnodes is filled with nodes
+ * that point at each subblock (e.g. each 32-byte block of a 512-block chunk).
+ *
+ * MessagePool is loosely inspired by TCMalloc. http://goog-perftools.sourceforge.net/doc/tcmalloc.html
+ */
+
+hv_size_t mp_init(struct MessagePool *mp, hv_size_t numKB);
+
+void mp_free(struct MessagePool *mp);
+
+/**
+ * Adds a message to the pool and returns a pointer to the copy. Returns NULL
+ * if no space was available in the pool.
+ */
+struct HvMessage *mp_addMessage(struct MessagePool *mp, const struct HvMessage *m);
+
+void mp_freeMessage(struct MessagePool *mp, struct HvMessage *m);
+
+#endif // _MESSAGE_POOL_H_
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/projects/heavy/envelopeTrigger/MessageQueue.c	Thu Nov 12 14:59:46 2015 +0000
@@ -0,0 +1,218 @@
+/**
+ * Copyright (c) 2014, 2015, Enzien Audio Ltd.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "MessageQueue.h"
+#include "Utils.h"
+
+hv_size_t mq_init(MessageQueue *q) {
+  q->head = NULL;
+  q->tail = NULL;
+  q->pool = NULL;
+  return mp_init(&q->mp, 1);
+}
+
+void mq_initWithPoolSize(MessageQueue *q, hv_size_t poolSizeKB) {
+  q->head = NULL;
+  q->tail = NULL;
+  q->pool = NULL;
+  mp_init(&q->mp, poolSizeKB);
+}
+
+void mq_free(MessageQueue *q) {
+  mq_clear(q);
+  while (q->pool != NULL) {
+    MessageNode *n = q->pool;
+    q->pool = q->pool->next;
+    hv_free(n);
+  }
+  mp_free(&q->mp);
+}
+
+static MessageNode *mq_getOrCreateNodeFromPool(MessageQueue *q) {
+  if (q->pool == NULL) {
+    // if necessary, create a new empty node
+    q->pool = (MessageNode *) hv_malloc(sizeof(MessageNode));
+    q->pool->next = NULL;
+  }
+  MessageNode *node = q->pool;
+  q->pool = q->pool->next;
+  return node;
+}
+
+int mq_size(MessageQueue *q) {
+    int size = 0;
+    MessageNode *n = q->head;
+    while (n != NULL) {
+        ++size;
+        n = n->next;
+    }
+    return size;
+}
+
+HvMessage *mq_addMessage(MessageQueue *q, const HvMessage *m, int let,
+    void (*sendMessage)(struct HvBase *, int, const HvMessage *)) {
+  MessageNode *node = mq_getOrCreateNodeFromPool(q);
+  node->m = mp_addMessage(&q->mp, m);
+  node->let = let;
+  node->sendMessage = sendMessage;
+  node->prev = NULL;
+  node->next = NULL;
+
+  if (q->tail != NULL) {
+    // the list already contains elements
+    q->tail->next = node;
+    node->prev = q->tail;
+    q->tail = node;
+  } else {
+    // the list is empty
+    node->prev = NULL;
+    q->head = node;
+    q->tail = node;
+  }
+  return mq_node_getMessage(node);
+}
+
+HvMessage *mq_addMessageByTimestamp(MessageQueue *q, HvMessage *m, int let,
+    void (*sendMessage)(struct HvBase *, int, const HvMessage *)) {
+  if (mq_hasMessage(q)) {
+    MessageNode *n = mq_getOrCreateNodeFromPool(q);
+    n->m = mp_addMessage(&q->mp, m);
+    n->let = let;
+    n->sendMessage = sendMessage;
+
+    if (msg_getTimestamp(m) < msg_getTimestamp(q->head->m)) {
+      // the message occurs before the current head
+      n->next = q->head;
+      q->head->prev = n;
+      n->prev = NULL;
+      q->head = n;
+    } else if (msg_getTimestamp(m) >= msg_getTimestamp(q->tail->m)) {
+      // the message occurs after the current tail
+      n->next = NULL;
+      n->prev = q->tail;
+      q->tail->next = n;
+      q->tail = n;
+    } else {
+      // the message occurs somewhere between the head and tail
+      MessageNode *node = q->head;
+      while (node != NULL) {
+        if (m->timestamp < msg_getTimestamp(node->next->m)) {
+          MessageNode *r = node->next;
+          node->next = n;
+          n->next = r;
+          n->prev = node;
+          r->prev = n;
+          break;
+        }
+        node = node->next;
+      }
+    }
+    return n->m;
+  } else {
+    // add a message to the head
+    return mq_addMessage(q, m, let, sendMessage);
+  }
+}
+
+void mq_pop(MessageQueue *q) {
+  if (mq_hasMessage(q)) {
+    MessageNode *n = q->head;
+
+    mp_freeMessage(&q->mp, n->m);
+    n->m = NULL;
+
+    n->let = 0;
+    n->sendMessage = NULL;
+
+    q->head = n->next;
+    if (q->head == NULL) {
+      q->tail = NULL;
+    } else {
+      q->head->prev = NULL;
+    }
+    n->next = q->pool;
+    n->prev = NULL;
+    q->pool = n;
+  }
+}
+
+void mq_removeMessage(MessageQueue *q, HvMessage *m, void (*sendMessage)(struct HvBase *, int, const HvMessage *)) {
+  if (mq_hasMessage(q)) {
+    if (mq_node_getMessage(q->head) == m) { // msg in head node
+      // only remove the message if sendMessage is the same as the stored one,
+      // if the sendMessage argument is NULL, it is not checked and will remove any matching message pointer
+      if (sendMessage == NULL || q->head->sendMessage == sendMessage) {
+        mq_pop(q);
+      }
+    } else {
+      MessageNode *prevNode = q->head;
+      MessageNode *currNode = q->head->next;
+      while ((currNode != NULL) && (currNode->m != m)) {
+        prevNode = currNode;
+        currNode = currNode->next;
+      }
+      if (currNode != NULL) {
+        if (sendMessage == NULL || currNode->sendMessage == sendMessage) {
+          mp_freeMessage(&q->mp, m);
+          currNode->m = NULL;
+          currNode->let = 0;
+          currNode->sendMessage = NULL;
+          if (currNode == q->tail) { // msg in tail node
+            prevNode->next = NULL;
+            q->tail = prevNode;
+          } else { // msg in middle node
+            prevNode->next = currNode->next;
+            currNode->next->prev = prevNode;
+          }
+          currNode->next = (q->pool == NULL) ? NULL : q->pool;
+          currNode->prev = NULL;
+          q->pool = currNode;
+        }
+      }
+    }
+  }
+}
+
+void mq_clear(MessageQueue *q) {
+  while (mq_hasMessage(q)) {
+    mq_pop(q);
+  }
+}
+
+void mq_clearAfter(MessageQueue *q, const double timestamp) {
+  MessageNode *n = q->tail;
+  while (n != NULL && timestamp <= msg_getTimestamp(n->m)) {
+    // free the node's message
+    mp_freeMessage(&q->mp, n->m);
+    n->m = NULL;
+    n->let = 0;
+    n->sendMessage = NULL;
+
+    // the tail points at the previous node
+    q->tail = n->prev;
+
+    // put the node back in the pool
+    n->next = q->pool;
+    n->prev = NULL;
+    if (q->pool != NULL) q->pool->prev = n;
+    q->pool = n;
+
+    // update the tail node
+    n = q->tail;
+  }
+
+  if (q->tail == NULL) q->head = NULL;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/projects/heavy/envelopeTrigger/MessageQueue.h	Thu Nov 12 14:59:46 2015 +0000
@@ -0,0 +1,91 @@
+/**
+ * Copyright (c) 2014, 2015, Enzien Audio Ltd.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _MESSAGE_QUEUE_H_
+#define _MESSAGE_QUEUE_H_
+
+#include "HvMessage.h"
+#include "MessagePool.h"
+
+struct HvBase;
+
+typedef struct MessageNode {
+  struct MessageNode *prev; // doubly linked list
+  struct MessageNode *next;
+  HvMessage *m;
+  void (*sendMessage)(struct HvBase *, int, const HvMessage *);
+  int let;
+} MessageNode;
+
+/** A doubly linked list containing scheduled messages. */
+typedef struct MessageQueue {
+  MessageNode *head; // the head of the queue
+  MessageNode *tail; // the tail of the queue
+  MessageNode *pool; // the head of the reserve pool
+  MessagePool mp;
+} MessageQueue;
+
+hv_size_t mq_init(MessageQueue *q);
+
+void mq_initWithPoolSize(MessageQueue *q, hv_size_t poolSizeKB);
+
+void mq_free(MessageQueue *q);
+
+int mq_size(MessageQueue *q);
+
+static inline HvMessage *mq_node_getMessage(MessageNode *n) {
+  return n->m;
+}
+
+static inline int mq_node_getLet(MessageNode *n) {
+  return n->let;
+}
+
+static inline bool mq_hasMessage(MessageQueue *q) {
+  return (q->head != NULL);
+}
+
+// true if there is a message and it occurs before (<) timestamp
+static inline bool mq_hasMessageBefore(MessageQueue *const q, const hv_uint32_t timestamp) {
+  return mq_hasMessage(q) && (msg_getTimestamp(mq_node_getMessage(q->head)) < timestamp);
+}
+
+static inline MessageNode *mq_peek(MessageQueue *q) {
+  return q->head;
+}
+
+/** Appends the message to the end of the queue. */
+HvMessage *mq_addMessage(MessageQueue *q, const HvMessage *m, int let,
+    void (*sendMessage)(struct HvBase *, int, const HvMessage *));
+
+/** Insert in ascending order the message acccording to its timestamp. */
+HvMessage *mq_addMessageByTimestamp(MessageQueue *q, HvMessage *m, int let,
+    void (*sendMessage)(struct HvBase *, int, const HvMessage *));
+
+/** Pop the message at the head of the queue (and free its memory). */
+void mq_pop(MessageQueue *q);
+
+/** Remove a message from the queue (and free its memory) */
+void mq_removeMessage(MessageQueue *q, HvMessage *m,
+    void (*sendMessage)(struct HvBase *, int, const HvMessage *));
+
+/** Clears (and frees) all messages in the queue. */
+void mq_clear(MessageQueue *q);
+
+/** Removes all messages occuring at or after the given timestamp. */
+void mq_clearAfter(MessageQueue *q, const double timestamp);
+
+#endif // _MESSAGE_QUEUE_H_
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/projects/heavy/envelopeTrigger/SignalBiquad.c	Thu Nov 12 14:59:46 2015 +0000
@@ -0,0 +1,192 @@
+/**
+ * Copyright (c) 2014, 2015, Enzien Audio Ltd.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "SignalBiquad.h"
+
+// http://reanimator-web.appspot.com/articles/simdiir
+// http://musicdsp.org/files/Audio-EQ-Cookbook.txt
+
+hv_size_t sBiquad_init(SignalBiquad *o) {
+#if HV_SIMD_AVX
+  o->xm1 = _mm256_setzero_ps();
+  o->xm2 = _mm256_setzero_ps();
+#elif HV_SIMD_SSE
+  o->xm1 = _mm_setzero_ps();
+  o->xm2 = _mm_setzero_ps();
+#elif HV_SIMD_NEON
+  o->xm1 = vdupq_n_f32(0.0f);
+  o->xm2 = vdupq_n_f32(0.0f);
+#else // HV_SIMD_NONE
+  o->x1 = 0.0f;
+  o->x2 = 0.0f;
+#endif
+  o->y1 = 0.0f;
+  o->y2 = 0.0f;
+  return 0;
+}
+
+void __hv_biquad_f(SignalBiquad *o, hv_bInf_t bIn, hv_bInf_t bX0, hv_bInf_t bX1, hv_bInf_t bX2, hv_bInf_t bY1, hv_bInf_t bY2, hv_bOutf_t bOut) {
+#if HV_SIMD_AVX
+  __m256 a = _mm256_mul_ps(bIn, bX0);
+  __m256 b = _mm256_mul_ps(o->xm1, bX1);
+  __m256 c = _mm256_mul_ps(o->xm2, bX2);
+  __m256 d = _mm256_add_ps(a, b);
+  __m256 e = _mm256_add_ps(c, d); // bIn*bX0 + o->x1*bX1 + o->x2*bX2
+  float y0 = e[0] - o->y1*bY1[0] - o->y2*bY2[0];
+  float y1 = e[1] - y0*bY1[1] - o->y1*bY2[1];
+  float y2 = e[2] - y1*bY1[2] - y0*bY2[2];
+  float y3 = e[3] - y2*bY1[3] - y1*bY2[3];
+  float y4 = e[4] - y3*bY1[4] - y2*bY2[4];
+  float y5 = e[5] - y4*bY1[5] - y3*bY2[5];
+  float y6 = e[6] - y5*bY1[6] - y4*bY2[6];
+  float y7 = e[7] - y6*bY1[7] - y5*bY2[7];
+
+  o->xm2 = o->xm1;
+  o->xm1 = bIn;
+  o->y1 = y7;
+  o->y2 = y6;
+
+  *bOut = _mm256_set_ps(y7, y6, y5, y4, y3, y2, y1, y0);
+#elif HV_SIMD_SSE
+  __m128 a = _mm_mul_ps(bIn, bX0);
+  __m128 b = _mm_mul_ps(o->xm1, bX1);
+  __m128 c = _mm_mul_ps(o->xm2, bX2);
+  __m128 d = _mm_add_ps(a, b);
+  __m128 e = _mm_add_ps(c, d);
+  float y0 = e[0] - o->y1*bY1[0] - o->y2*bY2[0];
+  float y1 = e[1] - y0*bY1[1] - o->y1*bY2[1];
+  float y2 = e[2] - y1*bY1[2] - y0*bY2[2];
+  float y3 = e[3] - y2*bY1[3] - y1*bY2[3];
+
+  o->xm2 = o->xm1;
+  o->xm1 = bIn;
+  o->y1 = y3;
+  o->y2 = y2;
+
+  *bOut = _mm_set_ps(y3, y2, y1, y0);
+#elif HV_SIMD_NEON
+  float32x4_t a = vmulq_f32(bIn, bX0);
+  float32x4_t b = vmulq_f32(o->xm1, bX1);
+  float32x4_t c = vmulq_f32(o->xm2, bX2);
+  float32x4_t d = vaddq_f32(a, b);
+  float32x4_t e = vaddq_f32(c, d);
+  float y0 = e[0] - o->y1*bY1[0] - o->y2*bY2[0];
+  float y1 = e[1] - y0*bY1[1] - o->y1*bY2[1];
+  float y2 = e[2] - y1*bY1[2] - y0*bY2[2];
+  float y3 = e[3] - y2*bY1[3] - y1*bY2[3];
+
+  o->xm2 = o->xm1;
+  o->xm1 = bIn;
+  o->y1 = y3;
+  o->y2 = y2;
+
+  *bOut = (float32x4_t) {y0, y1, y2, y3};
+#else
+  const float y = bIn*bX0 + o->x1*bX1 + o->x2*bX2 - o->y1*bY1 - o->y2*bY2;
+  o->x2 = o->x1; o->x1 = bIn;
+  o->y2 = o->y1; o->y1 = y;
+  *bOut = y;
+#endif
+}
+
+static void sBiquad_k_updateCoefficients(SignalBiquad_k *const o) {
+  // calculate all filter coefficients in the double domain
+#if HV_SIMD_AVX || HV_SIMD_SSE || HV_SIMD_NEON
+  double b0 = (double) o->b0;
+  double b1 = (double) o->b1;
+  double b2 = (double) o->b2;
+  double a1 = (double) -o->a1;
+  double a2 = (double) -o->a2;
+
+  double coeffs[4][8] =
+  {
+    { 0,  0,  0,  b0, b1, b2, a1, a2 },
+    { 0,  0,  b0, b1, b2, 0,  a2, 0  },
+    { 0,  b0, b1, b2, 0,  0,  0,  0  },
+    { b0, b1, b2, 0,  0,  0,  0,  0  },
+  };
+
+  for (int i = 0; i < 8; i++) {
+    coeffs[1][i] += a1*coeffs[0][i];
+    coeffs[2][i] += a1*coeffs[1][i] + a2*coeffs[0][i];
+    coeffs[3][i] += a1*coeffs[2][i] + a2*coeffs[1][i];
+  }
+
+#if HV_SIMD_AVX || HV_SIMD_SSE
+  o->coeff_xp3 = _mm_set_ps((float) coeffs[3][0], (float) coeffs[2][0], (float) coeffs[1][0], (float) coeffs[0][0]);
+  o->coeff_xp2 = _mm_set_ps((float) coeffs[3][1], (float) coeffs[2][1], (float) coeffs[1][1], (float) coeffs[0][1]);
+  o->coeff_xp1 = _mm_set_ps((float) coeffs[3][2], (float) coeffs[2][2], (float) coeffs[1][2], (float) coeffs[0][2]);
+  o->coeff_x0 =  _mm_set_ps((float) coeffs[3][3], (float) coeffs[2][3], (float) coeffs[1][3], (float) coeffs[0][3]);
+  o->coeff_xm1 = _mm_set_ps((float) coeffs[3][4], (float) coeffs[2][4], (float) coeffs[1][4], (float) coeffs[0][4]);
+  o->coeff_xm2 = _mm_set_ps((float) coeffs[3][5], (float) coeffs[2][5], (float) coeffs[1][5], (float) coeffs[0][5]);
+  o->coeff_ym1 = _mm_set_ps((float) coeffs[3][6], (float) coeffs[2][6], (float) coeffs[1][6], (float) coeffs[0][6]);
+  o->coeff_ym2 = _mm_set_ps((float) coeffs[3][7], (float) coeffs[2][7], (float) coeffs[1][7], (float) coeffs[0][7]);
+#else // HV_SIMD_NEON
+  o->coeff_xp3 = (float32x4_t) {(float) coeffs[0][0], (float) coeffs[1][0], (float) coeffs[2][0], (float) coeffs[3][0]};
+  o->coeff_xp2 = (float32x4_t) {(float) coeffs[0][1], (float) coeffs[1][1], (float) coeffs[2][1], (float) coeffs[3][1]};
+  o->coeff_xp1 = (float32x4_t) {(float) coeffs[0][2], (float) coeffs[1][2], (float) coeffs[2][2], (float) coeffs[3][2]};
+  o->coeff_x0 =  (float32x4_t) {(float) coeffs[0][3], (float) coeffs[1][3], (float) coeffs[2][3], (float) coeffs[3][3]};
+  o->coeff_xm1 = (float32x4_t) {(float) coeffs[0][4], (float) coeffs[1][4], (float) coeffs[2][4], (float) coeffs[3][4]};
+  o->coeff_xm2 = (float32x4_t) {(float) coeffs[0][5], (float) coeffs[1][5], (float) coeffs[2][5], (float) coeffs[3][5]};
+  o->coeff_ym1 = (float32x4_t) {(float) coeffs[0][6], (float) coeffs[1][6], (float) coeffs[2][6], (float) coeffs[3][6]};
+  o->coeff_ym2 = (float32x4_t) {(float) coeffs[0][7], (float) coeffs[1][7], (float) coeffs[2][7], (float) coeffs[3][7]};
+#endif
+#endif
+  // NOTE(mhroth): not necessary to calculate any coefficients for HV_SIMD_NONE case
+}
+
+hv_size_t sBiquad_k_init(SignalBiquad_k *o, float b0, float b1, float b2, float a1, float a2) {
+  // initialise filter coefficients
+  o->b0 = b0;
+  o->b1 = b1;
+  o->b2 = b2;
+  o->a1 = a1;
+  o->a2 = a2;
+  sBiquad_k_updateCoefficients(o);
+
+  // clear filter state
+#if HV_SIMD_AVX || HV_SIMD_SSE
+  o->xm1 = _mm_setzero_ps();
+  o->xm2 = _mm_setzero_ps();
+  o->ym1 = _mm_setzero_ps();
+  o->ym2 = _mm_setzero_ps();
+#elif HV_SIMD_NEON
+  o->xm1 = vdupq_n_f32(0.0f);
+  o->xm2 = vdupq_n_f32(0.0f);
+  o->ym1 = vdupq_n_f32(0.0f);
+  o->ym2 = vdupq_n_f32(0.0f);
+#else // HV_SIMD_NONE
+  o->xm1 = 0.0f;
+  o->xm2 = 0.0f;
+  o->ym1 = 0.0f;
+  o->ym2 = 0.0f;
+#endif
+  return 0;
+}
+
+void sBiquad_k_onMessage(SignalBiquad_k *o, int letIn, const HvMessage *const m) {
+  if (msg_isFloat(m,0)) {
+    switch (letIn) {
+      case 1: o->b0 = msg_getFloat(m,0); break;
+      case 2: o->b1 = msg_getFloat(m,0); break;
+      case 3: o->b2 = msg_getFloat(m,0); break;
+      case 4: o->a1 = msg_getFloat(m,0); break;
+      case 5: o->a2 = msg_getFloat(m,0); break;
+      default: return;
+    }
+    sBiquad_k_updateCoefficients(o);
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/projects/heavy/envelopeTrigger/SignalBiquad.h	Thu Nov 12 14:59:46 2015 +0000
@@ -0,0 +1,235 @@
+/**
+ * Copyright (c) 2014, 2015, Enzien Audio Ltd.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _HEAVY_SIGNAL_BIQUAD_H_
+#define _HEAVY_SIGNAL_BIQUAD_H_
+
+#include "HvBase.h"
+
+// http://en.wikipedia.org/wiki/Digital_biquad_filter
+typedef struct SignalBiquad {
+#if HV_SIMD_AVX
+  __m256 xm1;
+  __m256 xm2;
+#elif HV_SIMD_SSE
+  __m128 xm1;
+  __m128 xm2;
+#elif HV_SIMD_NEON
+  float32x4_t xm1;
+  float32x4_t xm2;
+#else // HV_SIMD_NONE
+  float x1;
+  float x2;
+#endif
+  float y1;
+  float y2;
+} SignalBiquad;
+
+hv_size_t sBiquad_init(SignalBiquad *o);
+
+void __hv_biquad_f(SignalBiquad *o,
+    hv_bInf_t bIn, hv_bInf_t bX0, hv_bInf_t bX1, hv_bInf_t bX2, hv_bInf_t bY1, hv_bInf_t bY2,
+    hv_bOutf_t bOut);
+
+typedef struct SignalBiquad_k {
+#if HV_SIMD_AVX || HV_SIMD_SSE
+  // preprocessed filter coefficients
+  __m128 coeff_xp3;
+  __m128 coeff_xp2;
+  __m128 coeff_xp1;
+  __m128 coeff_x0;
+  __m128 coeff_xm1;
+  __m128 coeff_xm2;
+  __m128 coeff_ym1;
+  __m128 coeff_ym2;
+
+  // filter state
+  __m128 xm1;
+  __m128 xm2;
+  __m128 ym1;
+  __m128 ym2;
+#elif HV_SIMD_NEON
+  float32x4_t coeff_xp3;
+  float32x4_t coeff_xp2;
+  float32x4_t coeff_xp1;
+  float32x4_t coeff_x0;
+  float32x4_t coeff_xm1;
+  float32x4_t coeff_xm2;
+  float32x4_t coeff_ym1;
+  float32x4_t coeff_ym2;
+  float32x4_t xm1;
+  float32x4_t xm2;
+  float32x4_t ym1;
+  float32x4_t ym2;
+#else // HV_SIMD_NONE
+  float xm1;
+  float xm2;
+  float ym1;
+  float ym2;
+#endif
+  // original filter coefficients
+  float b0; // x[0]
+  float b1; // x[-1]
+  float b2; // x[-2]
+  float a1; // y[-1]
+  float a2; // y[-2]
+} SignalBiquad_k;
+
+hv_size_t sBiquad_k_init(SignalBiquad_k *o, float x0, float x1, float x2, float y1, float y2);
+
+void sBiquad_k_onMessage(SignalBiquad_k *o, int letIn, const HvMessage *const m);
+
+static inline void __hv_biquad_k_f(SignalBiquad_k *o, hv_bInf_t bIn, hv_bOutf_t bOut) {
+#if HV_SIMD_AVX
+  const __m128 c_xp3 = o->coeff_xp3;
+  const __m128 c_xp2 = o->coeff_xp2;
+  const __m128 c_xp1 = o->coeff_xp1;
+  const __m128 c_x0 = o->coeff_x0;
+  const __m128 c_xm1 = o->coeff_xm1;
+  const __m128 c_xm2 = o->coeff_xm2;
+  const __m128 c_ym1 = o->coeff_ym1;
+  const __m128 c_ym2 = o->coeff_ym2;
+
+  // lower half
+  __m128 x3 = _mm_set1_ps(bIn[3]);
+  __m128 x2 = _mm_set1_ps(bIn[2]);
+  __m128 x1 = _mm_set1_ps(bIn[1]);
+  __m128 x0 = _mm_set1_ps(bIn[0]);
+  __m128 xm1 = o->xm1;
+  __m128 xm2 = o->xm2;
+  __m128 ym1 = o->ym1;
+  __m128 ym2 = o->ym2;
+
+  __m128 a = _mm_mul_ps(c_xp3, x3);
+  __m128 b = _mm_mul_ps(c_xp2, x2);
+  __m128 c = _mm_mul_ps(c_xp1, x1);
+  __m128 d = _mm_mul_ps(c_x0, x0);
+  __m128 e = _mm_mul_ps(c_xm1, xm1);
+  __m128 f = _mm_mul_ps(c_xm2, xm2);
+  __m128 g = _mm_mul_ps(c_ym1, ym1);
+  __m128 h = _mm_mul_ps(c_ym2, ym2);
+
+  __m128 i = _mm_add_ps(a, b);
+  __m128 j = _mm_add_ps(c, d);
+  __m128 k = _mm_add_ps(e, f);
+  __m128 l = _mm_add_ps(g, h);
+  __m128 m = _mm_add_ps(i, j);
+  __m128 n = _mm_add_ps(k, l);
+
+  __m128 lo_y = _mm_add_ps(m, n); // lower part of output buffer
+
+  // upper half
+  xm1 = x3;
+  xm2 = x2;
+  x3 = _mm_set1_ps(bIn[7]);
+  x2 = _mm_set1_ps(bIn[6]);
+  x1 = _mm_set1_ps(bIn[5]);
+  x0 = _mm_set1_ps(bIn[4]);
+  ym1 = _mm_set1_ps(lo_y[3]);
+  ym2 = _mm_set1_ps(lo_y[2]);
+
+  a = _mm_mul_ps(c_xp3, x3);
+  b = _mm_mul_ps(c_xp2, x2);
+  c = _mm_mul_ps(c_xp1, x1);
+  d = _mm_mul_ps(c_x0, x0);
+  e = _mm_mul_ps(c_xm1, xm1);
+  f = _mm_mul_ps(c_xm2, xm2);
+  g = _mm_mul_ps(c_ym1, ym1);
+  h = _mm_mul_ps(c_ym2, ym2);
+
+  i = _mm_add_ps(a, b);
+  j = _mm_add_ps(c, d);
+  k = _mm_add_ps(e, f);
+  l = _mm_add_ps(g, h);
+  m = _mm_add_ps(i, j);
+  n = _mm_add_ps(k, l);
+
+  __m128 up_y = _mm_add_ps(m, n); // upper part of output buffer
+
+  o->xm1 = x3;
+  o->xm2 = x2;
+  o->ym1 = _mm_set1_ps(up_y[3]);
+  o->ym2 = _mm_set1_ps(up_y[2]);
+
+  *bOut = _mm256_insertf128_ps(_mm256_castps128_ps256(lo_y), up_y, 1);
+#elif HV_SIMD_SSE
+  __m128 x3 = _mm_set1_ps(bIn[3]);
+  __m128 x2 = _mm_set1_ps(bIn[2]);
+  __m128 x1 = _mm_set1_ps(bIn[1]);
+  __m128 x0 = _mm_set1_ps(bIn[0]);
+
+  __m128 a = _mm_mul_ps(o->coeff_xp3, x3);
+  __m128 b = _mm_mul_ps(o->coeff_xp2, x2);
+  __m128 c = _mm_mul_ps(o->coeff_xp1, x1);
+  __m128 d = _mm_mul_ps(o->coeff_x0, x0);
+  __m128 e = _mm_mul_ps(o->coeff_xm1, o->xm1);
+  __m128 f = _mm_mul_ps(o->coeff_xm2, o->xm2);
+  __m128 g = _mm_mul_ps(o->coeff_ym1, o->ym1);
+  __m128 h = _mm_mul_ps(o->coeff_ym2, o->ym2);
+  __m128 i = _mm_add_ps(a, b);
+  __m128 j = _mm_add_ps(c, d);
+  __m128 k = _mm_add_ps(e, f);
+  __m128 l = _mm_add_ps(g, h);
+  __m128 m = _mm_add_ps(i, j);
+  __m128 n = _mm_add_ps(k, l);
+
+  __m128 y = _mm_add_ps(m, n);
+
+  o->xm1 = x3;
+  o->xm2 = x2;
+  o->ym1 = _mm_set1_ps(y[3]);
+  o->ym2 = _mm_set1_ps(y[2]);
+
+  *bOut = y;
+#elif HV_SIMD_NEON
+  float32x4_t x3 = vdupq_n_f32(bIn[3]);
+  float32x4_t x2 = vdupq_n_f32(bIn[2]);
+  float32x4_t x1 = vdupq_n_f32(bIn[1]);
+  float32x4_t x0 = vdupq_n_f32(bIn[0]);
+
+  float32x4_t a = vmulq_f32(o->coeff_xp3, x3);
+  float32x4_t b = vmulq_f32(o->coeff_xp2, x2);
+  float32x4_t c = vmulq_f32(o->coeff_xp1, x1);
+  float32x4_t d = vmulq_f32(o->coeff_x0, x0);
+  float32x4_t e = vmulq_f32(o->coeff_xm1, o->xm1);
+  float32x4_t f = vmulq_f32(o->coeff_xm2, o->xm2);
+  float32x4_t g = vmulq_f32(o->coeff_ym1, o->ym1);
+  float32x4_t h = vmulq_f32(o->coeff_ym2, o->ym2);
+  float32x4_t i = vaddq_f32(a, b);
+  float32x4_t j = vaddq_f32(c, d);
+  float32x4_t k = vaddq_f32(e, f);
+  float32x4_t l = vaddq_f32(g, h);
+  float32x4_t m = vaddq_f32(i, j);
+  float32x4_t n = vaddq_f32(k, l);
+  float32x4_t y = vaddq_f32(m, n);
+
+  o->xm1 = x3;
+  o->xm2 = x2;
+  o->ym1 = vdupq_n_f32(y[3]);
+  o->ym2 = vdupq_n_f32(y[2]);
+
+  *bOut = y;
+#else // HV_SIMD_NONE
+  float y = o->b0*bIn + o->b1*o->xm1 + o->b2*o->xm2 - o->a1*o->ym1 - o->a2*o->ym2;
+  o->xm2 = o->xm1;
+  o->xm1 = bIn;
+  o->ym2 = o->ym1;
+  o->ym1 = y;
+  *bOut = y;
+#endif
+}
+
+#endif // _HEAVY_SIGNAL_BIQUAD_H_
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/projects/heavy/envelopeTrigger/SignalDel1.c	Thu Nov 12 14:59:46 2015 +0000
@@ -0,0 +1,46 @@
+/**
+ * Copyright (c) 2014, 2015, Enzien Audio Ltd.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "SignalDel1.h"
+
+hv_size_t sDel1_init(SignalDel1 *o) {
+#if HV_SIMD_AVX
+  o->x = _mm256_setzero_ps();
+#elif HV_SIMD_SSE
+  o->x = _mm_setzero_ps();
+#elif HV_SIMD_NEON
+  o->x = vdupq_n_f32(0.0f);
+#else
+  o->x = 0.0f;
+#endif
+  return 0;
+}
+
+void sDel1_onMessage(HvBase *_c, SignalDel1 *o, int letIn, const HvMessage *m) {
+  if (letIn == 2) {
+    if (msg_compareSymbol(m, 0, "clear")) {
+#if HV_SIMD_AVX
+      o->x = _mm256_setzero_ps();
+#elif HV_SIMD_SSE
+      o->x = _mm_setzero_ps();
+#elif HV_SIMD_NEON
+      o->x = vdupq_n_f32(0.0f);
+#else
+      o->x = 0.0f;
+#endif
+    }
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/projects/heavy/envelopeTrigger/SignalDel1.h	Thu Nov 12 14:59:46 2015 +0000
@@ -0,0 +1,49 @@
+/**
+ * Copyright (c) 2014, 2015, Enzien Audio Ltd.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _SIGNAL_DEL1_H_
+#define _SIGNAL_DEL1_H_
+
+#include "HvBase.h"
+
+typedef struct SignalDel1 {
+  hv_bufferf_t x;
+} SignalDel1;
+
+hv_size_t sDel1_init(SignalDel1 *o);
+
+void sDel1_onMessage(HvBase *_c, SignalDel1 *o, int letIn, const HvMessage *m);
+
+static inline void __hv_del1_f(SignalDel1 *o, hv_bInf_t bIn0, hv_bOutf_t bOut) {
+#if HV_SIMD_AVX
+  __m256 x = _mm256_permute_ps(bIn0, _MM_SHUFFLE(2,1,0,3)); // [3 0 1 2 7 4 5 6]
+  __m256 n = _mm256_permute2f128_ps(o->x,x,0x1);            // [h e f g 3 0 1 2]
+  *bOut = _mm256_blend_ps(x, n, 0x11);                      // [g 0 1 2 3 4 5 6]
+  o->x = x;
+#elif HV_SIMD_SSE
+  __m128 n = _mm_blend_ps(o->x, bIn0, 0x7);
+  *bOut = _mm_shuffle_ps(n, n, _MM_SHUFFLE(2,1,0,3));
+  o->x = bIn0;
+#elif HV_SIMD_NEON
+  *bOut = vextq_f32(o->x, bIn0, 3);
+  o->x = bIn0;
+#else
+  *bOut = o->x;
+  o->x = bIn0;
+#endif
+}
+
+#endif // _SIGNAL_DEL1_H_
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/projects/heavy/envelopeTrigger/SignalPhasor.c	Thu Nov 12 14:59:46 2015 +0000
@@ -0,0 +1,123 @@
+/**
+ * Copyright (c) 2014, 2015, Enzien Audio Ltd.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "SignalPhasor.h"
+
+// input phase is in the range of [0,1]. It is independent of o->phase.
+#if HV_SIMD_AVX
+static void sPhasor_updatePhase(SignalPhasor *o, float p) {
+  o->phase = _mm256_set_ps(
+      p+1.0f+7.0f*o->step.f2sc, p+1.0f+6.0f*o->step.f2sc,
+      p+1.0f+5.0f*o->step.f2sc, p+1.0f+4.0f*o->step.f2sc,
+      p+1.0f+3.0f*o->step.f2sc, p+1.0f+2.0f*o->step.f2sc,
+      p+1.0f+o->step.f2sc,      p+1.0f);
+
+  // ensure that o->phase is still in range [1,2]
+  o->phase = _mm256_or_ps(_mm256_andnot_ps(
+      _mm256_set1_ps(-INFINITY), o->phase), _mm256_set1_ps(1.0f));
+#elif HV_SIMD_SSE
+static void sPhasor_updatePhase(SignalPhasor *o, hv_uint32_t p) {
+  o->phase = _mm_set_epi32(3*o->step.s+p, 2*o->step.s+p, o->step.s+p, p);
+#elif HV_SIMD_NEON
+static void sPhasor_updatePhase(SignalPhasor *o, hv_uint32_t p) {
+  o->phase = (uint32x4_t) {p, o->step.s+p, 2*o->step.s+p, 3*o->step.s+p};
+#else // HV_SIMD_NONE
+static void sPhasor_updatePhase(SignalPhasor *o, hv_uint32_t p) {
+  o->phase = p;
+#endif
+}
+
+static void sPhasor_updateFrequency(SignalPhasor *o, float f, double r) {
+#if HV_SIMD_AVX
+  o->step.f2sc = (float) (f/r);
+  o->inc = _mm256_set1_ps((float) (8.0f*f/r));
+  sPhasor_updatePhase(o, o->phase[0]);
+#elif HV_SIMD_SSE
+  o->step.s = (hv_int32_t) (f*(4294967296.0/r));
+  o->inc = _mm_set1_epi32(4*o->step.s);
+  sPhasor_updatePhase(o, (hv_uint32_t) (o->phase[0] & 0xFFFFFFFFL));
+#elif HV_SIMD_NEON
+  o->step.s = (hv_int32_t) (f*(4294967296.0/r));
+  o->inc = vdupq_n_s32(4*o->step.s);
+  sPhasor_updatePhase(o, vgetq_lane_u32(o->phase, 0));
+#else // HV_SIMD_NONE
+  o->step.s = (hv_int32_t) (f*(4294967296.0/r));
+  o->inc = o->step.s;
+  // no need to update phase
+#endif
+}
+
+hv_size_t sPhasor_init(SignalPhasor *o, double samplerate) {
+#if HV_SIMD_AVX
+  o->phase = _mm256_set1_ps(1.0f);
+  o->inc = _mm256_setzero_ps();
+  o->step.f2sc = (float) (1.0/samplerate);
+#elif HV_SIMD_SSE
+  o->phase = _mm_setzero_si128();
+  o->inc = _mm_setzero_si128();
+  o->step.f2sc = (float) (4294967296.0/samplerate);
+#elif HV_SIMD_NEON
+  o->phase = vdupq_n_u32(0);
+  o->inc = vdupq_n_s32(0);
+  o->step.f2sc = (float) (4294967296.0/samplerate);
+#else // HV_SIMD_NONE
+  o->phase = 0;
+  o->inc = 0;
+  o->step.f2sc = (float) (4294967296.0/samplerate);
+#endif
+  return 0;
+}
+
+void sPhasor_onMessage(HvBase *_c, SignalPhasor *o, int letIn, const HvMessage *m) {
+  if (letIn == 1) {
+    if (msg_isFloat(m,0)) {
+      float phase = msg_getFloat(m,0);
+      while (phase < 0.0f) phase += 1.0f; // wrap phase to [0,1]
+      while (phase > 1.0f) phase -= 1.0f;
+#if HV_SIMD_AVX
+      sPhasor_updatePhase(o, phase);
+#else // HV_SIMD_SSE || HV_SIMD_NEON || HV_SIMD_NONE
+      sPhasor_updatePhase(o, (hv_int32_t) (phase * 4294967296.0));
+#endif
+    }
+  }
+}
+
+hv_size_t sPhasor_k_init(SignalPhasor *o, float frequency, double samplerate) {
+  sPhasor_updateFrequency(o, frequency, samplerate);
+  sPhasor_updatePhase(o, 0);
+  return 0;
+}
+
+void sPhasor_k_onMessage(HvBase *_c, SignalPhasor *o, int letIn, const HvMessage *m) {
+  if (msg_isFloat(m,0)) {
+    switch (letIn) {
+      case 0: sPhasor_updateFrequency(o, msg_getFloat(m,0), ctx_getSampleRate(_c)); break;
+      case 1: {
+        float phase = msg_getFloat(m,0);
+        while (phase < 0.0f) phase += 1.0f; // wrap phase to [0,1]
+        while (phase > 1.0f) phase -= 1.0f;
+#if HV_SIMD_AVX
+        sPhasor_updatePhase(o, phase);
+#else // HV_SIMD_SSE || HV_SIMD_NEON || HV_SIMD_NONE
+        sPhasor_updatePhase(o, (hv_uint32_t) (phase * 4294967296.0));
+#endif
+        break;
+      }
+      default: break;
+    }
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/projects/heavy/envelopeTrigger/SignalPhasor.h	Thu Nov 12 14:59:46 2015 +0000
@@ -0,0 +1,131 @@
+/**
+ * Copyright (c) 2014, 2015, Enzien Audio Ltd.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _HEAVY_SIGNAL_PHASOR_H_
+#define _HEAVY_SIGNAL_PHASOR_H_
+
+#include "HvBase.h"
+
+typedef struct SignalPhasor {
+#if HV_SIMD_AVX
+  __m256 phase; // current phase
+  __m256 inc;   // phase increment
+#elif HV_SIMD_SSE
+  __m128i phase;
+  __m128i inc;
+#elif HV_SIMD_NEON
+  uint32x4_t phase;
+  int32x4_t inc;
+#else // HV_SIMD_NONE
+  hv_uint32_t phase;
+  hv_int32_t inc;
+#endif
+  union {
+    float f2sc; // float to step conversion (used for __phasor~f)
+    hv_int32_t s; // step value (used for __phasor_k~f)
+  } step;
+} SignalPhasor;
+
+hv_size_t sPhasor_init(SignalPhasor *o, double samplerate);
+
+hv_size_t sPhasor_k_init(SignalPhasor *o, float frequency, double samplerate);
+
+void sPhasor_k_onMessage(HvBase *_c, SignalPhasor *o, int letIn, const HvMessage *m);
+
+void sPhasor_onMessage(HvBase *_c, SignalPhasor *o, int letIn, const HvMessage *m);
+
+static inline void __hv_phasor_f(SignalPhasor *o, hv_bInf_t bIn, hv_bOutf_t bOut) {
+#if HV_SIMD_AVX
+  __m256 p = _mm256_mul_ps(bIn, _mm256_set1_ps(o->step.f2sc)); // a b c d e f g h
+
+  __m256 z = _mm256_setzero_ps();
+
+  // http://stackoverflow.com/questions/11906814/how-to-rotate-an-sse-avx-vector
+  __m256 a = _mm256_permute_ps(p, _MM_SHUFFLE(2,1,0,3)); // d a b c h e f g
+  __m256 b = _mm256_permute2f128_ps(a, a, 0x01);         // h e f g d a b c
+  __m256 c = _mm256_blend_ps(a, b, 0x10);                // d a b c d e f g
+  __m256 d = _mm256_blend_ps(c, z, 0x01);                // 0 a b c d e f g
+  __m256 e = _mm256_add_ps(p, d); // a (a+b) (b+c) (c+d) (d+e) (e+f) (f+g) (g+h)
+
+  __m256 f = _mm256_permute_ps(e, _MM_SHUFFLE(1,0,3,2)); // (b+c) (c+d) a (a+b) (f+g) (g+h) (d+e) (e+f)
+  __m256 g = _mm256_permute2f128_ps(f, f, 0x01);         // (f+g) (g+h) (d+e) (e+f) (b+c) (c+d) a (a+b)
+  __m256 h = _mm256_blend_ps(f, g, 0x33);                // (b+c) (c+d) a (a+b) (b+c) (c+d) (d+e) (e+f)
+  __m256 i = _mm256_blend_ps(h, z, 0x03);                // 0 0 a (a+b) (b+c) (c+d) (d+e) (e+f)
+  __m256 j = _mm256_add_ps(e, i); // a (a+b) (a+b+c) (a+b+c+d) (b+c+d+e) (c+d+e+f) (d+e+f+g) (e+f+g+h)
+
+  __m256 k = _mm256_permute2f128_ps(j, z, 0x02);         // 0 0 0 0 a (a+b) (a+b+c) (a+b+c+d) (b+c+d+e)
+  __m256 m = _mm256_add_ps(j, k); // a (a+b) (a+b+c) (a+b+c+d) (a+b+c+d+e) (a+b+c+d+e+f) (a+b+c+d+e+f+g) (a+b+c+d+e+f+g+h)
+
+  __m256 n = _mm256_or_ps(_mm256_andnot_ps(
+      _mm256_set1_ps(-INFINITY),
+      _mm256_add_ps(o->phase, m)),
+      _mm256_set1_ps(1.0f));
+
+  *bOut = _mm256_sub_ps(n, _mm256_set1_ps(1.0f));
+
+  __m256 x = _mm256_permute_ps(n, _MM_SHUFFLE(3,3,3,3));
+  o->phase = _mm256_permute2f128_ps(x, x, 0x11);
+#elif HV_SIMD_SSE
+  __m128i p = _mm_cvtps_epi32(_mm_mul_ps(bIn, _mm_set1_ps(o->step.f2sc))); // convert frequency to step
+  p = _mm_add_epi32(p, _mm_slli_si128(p, 4)); // add incremental steps to phase (prefix sum)
+  p = _mm_add_epi32(p, _mm_slli_si128(p, 8)); // http://stackoverflow.com/questions/10587598/simd-prefix-sum-on-intel-cpu?rq=1
+  p = _mm_add_epi32(o->phase, p);
+  *bOut = _mm_sub_ps(_mm_castsi128_ps(
+      _mm_or_si128(_mm_srli_epi32(p, 9),
+      (__m128i) {0x3F8000003F800000L, 0x3F8000003F800000L})),
+      _mm_set1_ps(1.0f));
+  o->phase = _mm_shuffle_epi32(p, _MM_SHUFFLE(3,3,3,3));
+#elif HV_SIMD_NEON
+  int32x4_t p = vcvtq_s32_f32(vmulq_n_f32(bIn, o->step.f2sc));
+  p = vaddq_s32(p, vextq_s32(vdupq_n_s32(0), p, 3)); // http://stackoverflow.com/questions/11259596/arm-neon-intrinsics-rotation
+  p = vaddq_s32(p, vextq_s32(vdupq_n_s32(0), p, 2));
+  uint32x4_t pp = vaddq_u32(o->phase, vreinterpretq_u32_s32(p));
+  *bOut = vsubq_f32(vreinterpretq_f32_u32(vorrq_u32(vshrq_n_u32(pp, 9), vdupq_n_u32(0x3F800000))), vdupq_n_f32(1.0f));
+  o->phase = vdupq_n_u32(pp[3]);
+#else // HV_SIMD_NONE
+  const hv_uint32_t p = (o->phase >> 9) | 0x3F800000;
+  *bOut = *((float *) (&p)) - 1.0f;
+  o->phase += ((int) (bIn * o->step.f2sc));
+#endif
+}
+
+static inline void __hv_phasor_k_f(SignalPhasor *o, hv_bOutf_t bOut) {
+#if HV_SIMD_AVX
+  *bOut = _mm256_sub_ps(o->phase, _mm256_set1_ps(1.0f));
+  o->phase = _mm256_or_ps(_mm256_andnot_ps(
+      _mm256_set1_ps(-INFINITY),
+      _mm256_add_ps(o->phase, o->inc)),
+      _mm256_set1_ps(1.0f));
+#elif HV_SIMD_SSE
+  *bOut = _mm_sub_ps(_mm_castsi128_ps(
+      _mm_or_si128(_mm_srli_epi32(o->phase, 9),
+      (__m128i) {0x3F8000003F800000L, 0x3F8000003F800000L})),
+      _mm_set1_ps(1.0f));
+  o->phase = _mm_add_epi32(o->phase, o->inc);
+#elif HV_SIMD_NEON
+  *bOut = vsubq_f32(vreinterpretq_f32_u32(
+      vorrq_u32(vshrq_n_u32(o->phase, 9),
+      vdupq_n_u32(0x3F800000))),
+      vdupq_n_f32(1.0f));
+  o->phase = vaddq_u32(o->phase, vreinterpretq_u32_s32(o->inc));
+#else // HV_SIMD_NONE
+  const hv_uint32_t p = (o->phase >> 9) | 0x3F800000;
+  *bOut = *((float *) (&p)) - 1.0f;
+  o->phase += o->inc;
+#endif
+}
+
+#endif // _HEAVY_SIGNAL_PHASOR_H_
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/projects/heavy/envelopeTrigger/SignalRPole.c	Thu Nov 12 14:59:46 2015 +0000
@@ -0,0 +1,52 @@
+/**
+ * Copyright (c) 2014, 2015, Enzien Audio Ltd.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "SignalRPole.h"
+
+hv_size_t sRPole_init(SignalRPole *o) {
+#if HV_SIMD_AVX
+  sDel1_init(&o->sDel1_fxiLN);
+  sDel1_init(&o->sDel1_kjkpV);
+  sDel1_init(&o->sDel1_dkIWc);
+  sDel1_init(&o->sDel1_bVeoW);
+  sDel1_init(&o->sDel1_PulZn);
+  sDel1_init(&o->sDel1_yTFig);
+  sDel1_init(&o->sDel1_Is9Qf);
+  sDel1_init(&o->sDel1_LIyNt);
+  sDel1_init(&o->sDel1_VqpU3);
+  sDel1_init(&o->sDel1_ZVYeg);
+  sDel1_init(&o->sDel1_IVAZh);
+  sDel1_init(&o->sDel1_F8WrY);
+  sDel1_init(&o->sDel1_rkFMy);
+  sDel1_init(&o->sDel1_BeqSK);
+  __hv_zero_f(&o->ym);
+#elif HV_SIMD_SSE || HV_SIMD_NEON
+  sDel1_init(&o->sDel1_i8Twk);
+  sDel1_init(&o->sDel1_KYibU);
+  sDel1_init(&o->sDel1_spa5V);
+  sDel1_init(&o->sDel1_3HXdb);
+  sDel1_init(&o->sDel1_Aj1oK);
+  sDel1_init(&o->sDel1_jNX1g);
+  __hv_zero_f(&o->ym);
+#else
+  o->ym = 0.0f;
+#endif
+  return 0;
+}
+
+void sRPole_onMessage(HvBase *_c, SignalRPole *o, int letIn, const HvMessage *m) {
+  // TODO
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/projects/heavy/envelopeTrigger/SignalRPole.h	Thu Nov 12 14:59:46 2015 +0000
@@ -0,0 +1,123 @@
+/**
+ * Copyright (c) 2014, 2015, Enzien Audio Ltd.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _SIGNAL_RPOLE_H_
+#define _SIGNAL_RPOLE_H_
+
+#include "HvBase.h"
+#include "SignalDel1.h"
+#include "HeavyMath.h"
+
+// implements y[n] = x[n] - a*y[n-1]
+// H(z) = 1/(1+a*z^-1)
+typedef struct SignalRPole {
+#if HV_SIMD_AVX
+  SignalDel1 sDel1_fxiLN;
+  SignalDel1 sDel1_kjkpV;
+  SignalDel1 sDel1_dkIWc;
+  SignalDel1 sDel1_bVeoW;
+  SignalDel1 sDel1_PulZn;
+  SignalDel1 sDel1_yTFig;
+  SignalDel1 sDel1_Is9Qf;
+  SignalDel1 sDel1_LIyNt;
+  SignalDel1 sDel1_VqpU3;
+  SignalDel1 sDel1_ZVYeg;
+  SignalDel1 sDel1_IVAZh;
+  SignalDel1 sDel1_F8WrY;
+  SignalDel1 sDel1_rkFMy;
+  SignalDel1 sDel1_BeqSK;
+  hv_bufferf_t ym;
+#elif HV_SIMD_SSE || HV_SIMD_NEON
+  SignalDel1 sDel1_i8Twk;
+  SignalDel1 sDel1_KYibU;
+  SignalDel1 sDel1_spa5V;
+  SignalDel1 sDel1_3HXdb;
+  SignalDel1 sDel1_Aj1oK;
+  SignalDel1 sDel1_jNX1g;
+  hv_bufferf_t ym;
+#else
+  hv_bufferf_t ym;
+#endif
+} SignalRPole;
+
+hv_size_t sRPole_init(SignalRPole *o);
+
+void sRPole_onMessage(HvBase *_c, SignalRPole *o, int letIn, const HvMessage *m);
+
+static inline void __hv_rpole_f(SignalRPole *o, hv_bInf_t bIn0, hv_bInf_t bIn1, hv_bOutf_t bOut) {
+#if HV_SIMD_AVX
+  hv_bufferf_t a, b, c, d, e, f, g, i, j, k, l, m, n;
+  __hv_del1_f(&o->sDel1_fxiLN, bIn1, &a);
+  __hv_mul_f(bIn1, a, &b);
+  __hv_del1_f(&o->sDel1_kjkpV, a, &a);
+  __hv_mul_f(b, a, &c);
+  __hv_del1_f(&o->sDel1_dkIWc, a, &a);
+  __hv_mul_f(c, a, &d);
+  __hv_del1_f(&o->sDel1_bVeoW, a, &a);
+  __hv_mul_f(d, a, &e);
+  __hv_del1_f(&o->sDel1_PulZn, a, &a);
+  __hv_mul_f(e, a, &f);
+  __hv_del1_f(&o->sDel1_yTFig, a, &a);
+  __hv_mul_f(f, a, &g);
+  __hv_del1_f(&o->sDel1_Is9Qf, a, &a);
+  __hv_mul_f(g, a, &a);
+  __hv_del1_f(&o->sDel1_LIyNt, bIn0, &i);
+  __hv_del1_f(&o->sDel1_VqpU3, i, &j);
+  __hv_del1_f(&o->sDel1_ZVYeg, j, &k);
+  __hv_del1_f(&o->sDel1_IVAZh, k, &l);
+  __hv_del1_f(&o->sDel1_F8WrY, l, &m);
+  __hv_del1_f(&o->sDel1_rkFMy, m, &n);
+  __hv_mul_f(i, bIn1, &i);
+  __hv_sub_f(bIn0, i, &i);
+  __hv_fma_f(j, b, i, &i);
+  __hv_mul_f(k, c, &c);
+  __hv_sub_f(i, c, &c);
+  __hv_fma_f(l, d, c, &c);
+  __hv_mul_f(m, e, &e);
+  __hv_sub_f(c, e, &e);
+  __hv_fma_f(n, f, e, &e);
+  __hv_del1_f(&o->sDel1_BeqSK, n, &n);
+  __hv_mul_f(n, g, &g);
+  __hv_sub_f(e, g, &g);
+  __hv_fma_f(a, o->ym, g, &g);
+  o->ym = g;
+  *bOut = g;
+#elif HV_SIMD_SSE || HV_SIMD_NEON
+  hv_bufferf_t a, b, c, e, f;
+  __hv_del1_f(&o->sDel1_i8Twk, bIn1, &a);
+  __hv_mul_f(bIn1, a, &b);
+  __hv_del1_f(&o->sDel1_KYibU, a, &a);
+  __hv_mul_f(b, a, &c);
+  __hv_del1_f(&o->sDel1_spa5V, a, &a);
+  __hv_mul_f(c, a, &a);
+  __hv_del1_f(&o->sDel1_3HXdb, bIn0, &e);
+  __hv_del1_f(&o->sDel1_Aj1oK, e, &f);
+  __hv_mul_f(e, bIn1, &e);
+  __hv_sub_f(bIn0, e, &e);
+  __hv_fma_f(f, b, e, &e);
+  __hv_del1_f(&o->sDel1_jNX1g, f, &f);
+  __hv_mul_f(f, c, &c);
+  __hv_sub_f(e, c, &c);
+  __hv_fma_f(a, o->ym, c, &c);
+  o->ym = c;
+  *bOut = c;
+#else
+  *bOut = bIn0 - bIn1 * o->ym;
+  o->ym = *bOut;
+#endif
+}
+
+#endif // _SIGNAL_RPOLE_H_
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/projects/heavy/envelopeTrigger/SignalTabread.c	Thu Nov 12 14:59:46 2015 +0000
@@ -0,0 +1,71 @@
+/**
+ * Copyright (c) 2014, 2015, Enzien Audio Ltd.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "SignalTabread.h"
+
+hv_size_t sTabread_init(SignalTabread *o, HvTable *table, bool forceAlignedLoads) {
+  o->table = table;
+  o->head = 0;
+  o->forceAlignedLoads = forceAlignedLoads;
+  return 0;
+}
+
+void sTabread_onMessage(HvBase *_c, SignalTabread *o, int letIn, const HvMessage *const m) {
+  switch (letIn) {
+    case 0: {
+      if (o->table != NULL) {
+        switch (msg_getType(m,0)) {
+          case BANG: o->head = 0; break;
+          case FLOAT: {
+            hv_uint32_t h = (hv_uint32_t) hv_abs_f(msg_getFloat(m,0));
+            if (msg_getFloat(m,0) < 0.0f) {
+              // if input is negative, wrap around the end of the table
+              h = (hv_uint32_t) hTable_getSize(o->table) - h;
+            }
+            o->head = o->forceAlignedLoads ? h & ~HV_N_SIMD_MASK : h;
+            break;
+          }
+          default: break;
+        }
+      }
+      break;
+    }
+    case 1: {
+      if (msg_isHashLike(m,0)) {
+        o->table = ctx_getTableForHash(_c, msg_getHash(m,0));
+      }
+      break;
+    }
+    default: break;
+  }
+}
+
+
+
+#if HV_APPLE
+#pragma mark - Tabhead
+#endif
+
+void sTabhead_onMessage(HvBase *_c, SignalTabhead *o, const HvMessage *const m) {
+  if (msg_isHashLike(m,0)) {
+    o->table = ctx_getTableForHash(_c, msg_getHash(m,0));
+  }
+}
+
+hv_size_t sTabhead_init(SignalTabhead *o, HvTable *table) {
+  o->table = table;
+  return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/projects/heavy/envelopeTrigger/SignalTabread.h	Thu Nov 12 14:59:46 2015 +0000
@@ -0,0 +1,183 @@
+/**
+ * Copyright (c) 2014, 2015, Enzien Audio Ltd.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _HEAVY_SIGNAL_TABREAD_H_
+#define _HEAVY_SIGNAL_TABREAD_H_
+
+#include "HvBase.h"
+#include "HvTable.h"
+
+typedef struct SignalTabread {
+  HvTable *table; // the table to read
+  hv_uint32_t head;
+  bool forceAlignedLoads; // false by default, true if using __hv_tabread_f
+} SignalTabread;
+
+// random access to a table
+hv_size_t sTabread_init(SignalTabread *o, HvTable *table, bool forceAlignedLoads);
+
+
+
+#if HV_APPLE
+#pragma mark - Tabread - Random Access
+#endif
+
+static inline void __hv_tabread_if(SignalTabread *o, hv_bIni_t bIn, hv_bOutf_t bOut) {
+  const float *const b = hTable_getBuffer(o->table);
+#if HV_SIMD_AVX
+  hv_assert((int) (bIn[0] & 0xFFFFFFFFL) >= 0 && (int) (bIn[0] & 0xFFFFFFFFL) < hTable_getAllocated(o->table));
+  hv_assert((int) (bIn[0] >> 32) >= 0 && (int) ((bIn[0] & ~0xFFFFFFFFL) >> 32) < hTable_getAllocated(o->table));
+  hv_assert((int) (bIn[1] & 0xFFFFFFFFL) >= 0 && (int) (bIn[1] & 0xFFFFFFFFL) < hTable_getAllocated(o->table));
+  hv_assert((int) (bIn[1] >> 32) >= 0 && (int) ((bIn[1] & ~0xFFFFFFFFL) >> 32) < hTable_getAllocated(o->table));
+  hv_assert((int) (bIn[2] & 0xFFFFFFFFL) >= 0 && (int) (bIn[2] & 0xFFFFFFFFL) < hTable_getAllocated(o->table));
+  hv_assert((int) (bIn[2] >> 32) >= 0 && (int) ((bIn[2] & ~0xFFFFFFFFL) >> 32) < hTable_getAllocated(o->table));
+  hv_assert((int) (bIn[3] & 0xFFFFFFFFL) >= 0 && (int) (bIn[3] & 0xFFFFFFFFL) < hTable_getAllocated(o->table));
+  hv_assert((int) (bIn[3] >> 32) >= 0 && (int) ((bIn[3] & ~0xFFFFFFFFL) >> 32) < hTable_getAllocated(o->table));
+
+  *bOut = _mm256_set_ps(
+      b[(int) (bIn[3] >> 32)],
+      b[(int) (bIn[3] & 0xFFFFFFFFL)],
+      b[(int) (bIn[2] >> 32)],
+      b[(int) (bIn[2] & 0xFFFFFFFFL)],
+      b[(int) (bIn[1] >> 32)],
+      b[(int) (bIn[1] & 0xFFFFFFFFL)],
+      b[(int) (bIn[0] >> 32)],
+      b[(int) (bIn[0] & 0xFFFFFFFFL)]);
+#elif HV_SIMD_SSE
+  hv_assert((int) (bIn[0] & 0xFFFFFFFFL) >= 0 && (int) (bIn[0] & 0xFFFFFFFFL) < hTable_getAllocated(o->table));
+  hv_assert((int) (bIn[0] >> 32) >= 0 && (int) (bIn[0] >> 32) < hTable_getAllocated(o->table));
+  hv_assert((int) (bIn[1] & 0xFFFFFFFFL) >= 0 && (int) (bIn[1] & 0xFFFFFFFFL) < hTable_getAllocated(o->table));
+  hv_assert((int) (bIn[1] >> 32) >= 0 && (int) (bIn[1] >> 32) < hTable_getAllocated(o->table));
+
+  *bOut = _mm_set_ps(
+      b[(int) (bIn[1] >> 32)],
+      b[(int) (bIn[1] & 0xFFFFFFFFL)],
+      b[(int) (bIn[0] >> 32)],
+      b[(int) (bIn[0] & 0xFFFFFFFFL)]);
+#elif HV_SIMD_NEON
+  hv_assert((bIn[0] >= 0) && (bIn[0] < hTable_getAllocated(o->table)));
+  hv_assert((bIn[1] >= 0) && (bIn[1] < hTable_getAllocated(o->table)));
+  hv_assert((bIn[2] >= 0) && (bIn[2] < hTable_getAllocated(o->table)));
+  hv_assert((bIn[3] >= 0) && (bIn[3] < hTable_getAllocated(o->table)));
+
+  *bOut = (float32x4_t) {b[bIn[0]], b[bIn[1]], b[bIn[2]], b[bIn[3]]};
+#else // HV_SIMD_NONE
+  hv_assert(bIn >= 0 && ((hv_uint32_t) bIn < hTable_getAllocated(o->table)));
+
+  *bOut = b[bIn];
+#endif
+}
+
+
+
+#if HV_APPLE
+#pragma mark - Tabread - Linear Access
+#endif
+
+// this tabread never stops reading. It is mainly intended for linear reads that loop around a table.
+static inline void __hv_tabread_f(SignalTabread *o, hv_bOutf_t bOut) {
+  hv_assert((o->head + HV_N_SIMD) <= hTable_getAllocated(o->table)); // assert that we always read within the table bounds
+  hv_uint32_t head = o->head;
+#if HV_SIMD_AVX
+  *bOut = _mm256_load_ps(hTable_getBuffer(o->table) + head);
+#elif HV_SIMD_SSE
+  *bOut = _mm_load_ps(hTable_getBuffer(o->table) + head);
+#elif HV_SIMD_NEON
+  *bOut = vld1q_f32(hTable_getBuffer(o->table) + head);
+#else // HV_SIMD_NONE
+  *bOut = *(hTable_getBuffer(o->table) + head);
+#endif
+  o->head = head + HV_N_SIMD;
+}
+
+// unaligned linear tabread, as above
+static inline void __hv_tabreadu_f(SignalTabread *o, hv_bOutf_t bOut) {
+  hv_assert((o->head + HV_N_SIMD) <= hTable_getAllocated(o->table)); // assert that we always read within the table bounds
+  hv_uint32_t head = o->head;
+#if HV_SIMD_AVX
+  *bOut = _mm256_loadu_ps(hTable_getBuffer(o->table) + head);
+#elif HV_SIMD_SSE
+  *bOut = _mm_loadu_ps(hTable_getBuffer(o->table) + head);
+#elif HV_SIMD_NEON
+  *bOut = vld1q_f32(hTable_getBuffer(o->table) + head);
+#else // HV_SIMD_NONE
+  *bOut = *(hTable_getBuffer(o->table) + head);
+#endif
+  o->head = head + HV_N_SIMD;
+}
+
+// this tabread can be instructed to stop. It is mainly intended for linear reads that only process a portion of a buffer.
+static inline void __hv_tabread_stoppable_f(SignalTabread *o, hv_bOutf_t bOut) {
+#if HV_SIMD_AVX
+  if (o->head == ~0x0) {
+    *bOut = _mm256_setzero_ps();
+  } else {
+    *bOut = _mm256_load_ps(hTable_getBuffer(o->table) + o->head);
+    o->head += HV_N_SIMD;
+  }
+#elif HV_SIMD_SSE
+  if (o->head == ~0x0) {
+    *bOut = _mm_setzero_ps();
+  } else {
+    *bOut = _mm_load_ps(hTable_getBuffer(o->table) + o->head);
+    o->head += HV_N_SIMD;
+  }
+#elif HV_SIMD_NEON
+  if (o->head == ~0x0) {
+    *bOut = vdupq_n_f32(0.0f);
+  } else {
+    *bOut = vld1q_f32(hTable_getBuffer(o->table) + o->head);
+    o->head += HV_N_SIMD;
+  }
+#else // HV_SIMD_NONE
+  if (o->head == ~0x0) {
+    *bOut = 0.0f;
+  } else {
+    *bOut = *(hTable_getBuffer(o->table) + o->head);
+    o->head += HV_N_SIMD;
+  }
+#endif
+}
+
+void sTabread_onMessage(HvBase *_c, SignalTabread *o, int letIn, const HvMessage *const m);
+
+
+
+#if HV_APPLE
+#pragma mark - Tabhead
+#endif
+
+typedef struct SignalTabhead {
+  HvTable *table;
+} SignalTabhead;
+
+hv_size_t sTabhead_init(SignalTabhead *o, HvTable *table);
+
+static inline void __hv_tabhead_f(SignalTabhead *o, hv_bOutf_t bOut) {
+#if HV_SIMD_AVX
+  *bOut = _mm256_set1_ps((float) hTable_getHead(o->table));
+#elif HV_SIMD_SSE
+  *bOut = _mm_set1_ps((float) hTable_getHead(o->table));
+#elif HV_SIMD_NEON
+  *bOut = vdupq_n_f32((float32_t) hTable_getHead(o->table));
+#else // HV_SIMD_NONE
+  *bOut = (float) hTable_getHead(o->table);
+#endif
+}
+
+void sTabhead_onMessage(HvBase *_c, SignalTabhead *o, const HvMessage *const m);
+
+#endif // _HEAVY_SIGNAL_TABREAD_H_
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/projects/heavy/envelopeTrigger/SignalVar.c	Thu Nov 12 14:59:46 2015 +0000
@@ -0,0 +1,75 @@
+/**
+ * Copyright (c) 2014, 2015, Enzien Audio Ltd.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "SignalVar.h"
+
+// __var~f
+
+static void sVarf_update(SignalVarf *o, float k, float step, bool reverse) {
+#if HV_SIMD_AVX
+  if (reverse) o->v = _mm256_setr_ps(k+7.0f*step, k+6.0f*step, k+5.0f*step, k+4.0f*step, k+3.0f*step, k+2.0f*step, k+step, k);
+  else o->v = _mm256_set_ps(k+7.0f*step, k+6.0f*step, k+5.0f*step, k+4.0f*step, k+3.0f*step, k+2.0f*step, k+step, k);
+#elif HV_SIMD_SSE
+  if (reverse) o->v = _mm_setr_ps(k+3.0f*step, k+2.0f*step, k+step, k);
+  else o->v = _mm_set_ps(k+3.0f*step, k+2.0f*step, k+step, k);
+#elif HV_SIMD_NEON
+  if (reverse) o->v = (float32x4_t) {3.0f*step+k, 2.0f*step+k, step+k, k};
+  else o->v = (float32x4_t) {k, step+k, 2.0f*step+k, 3.0f*step+k};
+#else // HV_SIMD_NONE
+  o->v = k;
+#endif
+}
+
+hv_size_t sVarf_init(SignalVarf *o, float k, float step, bool reverse) {
+  sVarf_update(o, k, step, reverse);
+  return 0;
+}
+
+void sVarf_onMessage(HvBase *_c, SignalVarf *o, const HvMessage *m) {
+  if (msg_isFloat(m,0)) {
+    sVarf_update(o, msg_getFloat(m,0), msg_isFloat(m,1) ? msg_getFloat(m,1) : 0.0f, msg_getNumElements(m) == 3);
+  }
+}
+
+
+
+// __var~i
+
+static void sVari_update(SignalVari *o, int k, int step, bool reverse) {
+#if HV_SIMD_AVX
+  if (reverse) o->v = _mm256_setr_epi32(k+7*step, k+6*step, k+5*step, k+4*step, k+3*step, k+2*step, k+step, k);
+  else o->v = _mm256_set_epi32(k+7*step, k+6*step, k+5*step, k+4*step, k+3*step, k+2*step, k+step, k);
+#elif HV_SIMD_SSE
+  if (reverse) o->v = _mm_setr_epi32(k+3*step, k+2*step, k+step, k);
+  else o->v = _mm_set_epi32(k+3*step, k+2*step, k+step, k);
+#elif HV_SIMD_NEON
+  if (reverse) o->v = (int32x4_t) {3*step+k, 2*step+k, step+k, k};
+  else o->v = (int32x4_t) {k, step+k, 2*step+k, 3*step+k};
+#else // HV_SIMD_NEON
+  o->v = k;
+#endif
+}
+
+hv_size_t sVari_init(SignalVari *o, int k, int step, bool reverse) {
+  sVari_update(o, k, step, reverse);
+  return 0;
+}
+
+void sVari_onMessage(HvBase *_c, SignalVari *o, const HvMessage *m) {
+  if (msg_isFloat(m,0)) {
+    sVari_update(o, (int) msg_getFloat(m,0), msg_isFloat(m,1) ? (int) msg_getFloat(m,1) : 0, msg_getNumElements(m) == 3);
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/projects/heavy/envelopeTrigger/SignalVar.h	Thu Nov 12 14:59:46 2015 +0000
@@ -0,0 +1,87 @@
+/**
+ * Copyright (c) 2014, 2015, Enzien Audio Ltd.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _HEAVY_SIGNAL_VAR_H_
+#define _HEAVY_SIGNAL_VAR_H_
+
+#include "HvBase.h"
+
+// __var~f
+// __varset~f
+
+typedef struct SignalVarf {
+  hv_bufferf_t v;
+} SignalVarf;
+
+hv_size_t sVarf_init(SignalVarf *o, float k, float step, bool reverse);
+
+static inline void __hv_var_f(SignalVarf *o, hv_bOutf_t bOut) {
+  *bOut = o->v;
+}
+
+static inline void sVarsetf_process(SignalVarf *o, hv_bInf_t bIn) {
+  o->v = bIn;
+}
+
+void sVarf_onMessage(HvBase *_c, SignalVarf *o, const HvMessage *m);
+
+
+
+// __var~i
+// __varset~i
+
+typedef struct SignalVari {
+  hv_bufferi_t v;
+} SignalVari;
+
+hv_size_t sVari_init(SignalVari *o, int k, int step, bool reverse);
+
+static inline void __hv_var_i(SignalVari *o, hv_bOuti_t bOut) {
+  *bOut = o->v;
+}
+
+#if HV_SIMD_AVX
+#define __hv_var_k_i_0(_z,_a,_b,_c,_d,_e,_f,_g,_h) *_z=((__m256i)(__v8si) {_a,_b,_c,_d,_e,_f,_g,_h})
+#define __hv_var_k_i_1(_z,_a,_b,_c,_d,_e,_f,_g,_h) *_z=((__m256i)(__v8si) {_h,_g,_f,_e,_d,_c,_b,_a})
+#define __hv_var_k_f_0(_z,_a,_b,_c,_d,_e,_f,_g,_h) *_z=((__m256) {_a,_b,_c,_d,_e,_f,_g,_h})
+#define __hv_var_k_f_1(_z,_a,_b,_c,_d,_e,_f,_g,_h) *_z=((__m256) {_h,_g,_f,_e,_d,_c,_b,_a})
+#elif HV_SIMD_SSE
+#define __hv_var_k_i_0(_z,_a,_b,_c,_d,_e,_f,_g,_h) *_z=((__m128i)(__v4si) {_a,_b,_c,_d})
+#define __hv_var_k_i_1(_z,_a,_b,_c,_d,_e,_f,_g,_h) *_z=((__m128i)(__v4si) {_d,_c,_b,_a})
+#define __hv_var_k_f_0(_z,_a,_b,_c,_d,_e,_f,_g,_h) *_z=((__m128) {_a,_b,_c,_d})
+#define __hv_var_k_f_1(_z,_a,_b,_c,_d,_e,_f,_g,_h) *_z=((__m128) {_d,_c,_b,_a})
+#elif HV_SIMD_NEON
+#define __hv_var_k_i_0(_z,_a,_b,_c,_d,_e,_f,_g,_h) *_z=((int32x4_t) {_a,_b,_c,_d})
+#define __hv_var_k_i_1(_z,_a,_b,_c,_d,_e,_f,_g,_h) *_z=((int32x4_t) {_d,_c,_b,_a})
+#define __hv_var_k_f_0(_z,_a,_b,_c,_d,_e,_f,_g,_h) *_z=((float32x4_t) {_a,_b,_c,_d})
+#define __hv_var_k_f_1(_z,_a,_b,_c,_d,_e,_f,_g,_h) *_z=((float32x4_t) {_d,_c,_b,_a})
+#else // HV_SIMD_NONE
+#define __hv_var_k_i_0(_z,_a,_b,_c,_d,_e,_f,_g,_h) *_z=_a
+#define __hv_var_k_i_1(_z,_a,_b,_c,_d,_e,_f,_g,_h) *_z=_a
+#define __hv_var_k_f_0(_z,_a,_b,_c,_d,_e,_f,_g,_h) *_z=_a
+#define __hv_var_k_f_1(_z,_a,_b,_c,_d,_e,_f,_g,_h) *_z=_a
+#endif
+// r == 0: forwards, r == 1: backwards
+#define __hv_var_k_i(_z,_a,_b,_c,_d,_e,_f,_g,_h,_r) __hv_var_k_i_##_r(_z,_a,_b,_c,_d,_e,_f,_g,_h)
+#define __hv_var_k_f(_z,_a,_b,_c,_d,_e,_f,_g,_h,_r) __hv_var_k_f_##_r(_z,_a,_b,_c,_d,_e,_f,_g,_h)
+
+static inline void sVarseti_process(SignalVari *o, hv_bIni_t bIn) {
+  o->v = bIn;
+}
+
+void sVari_onMessage(HvBase *_c, SignalVari *o, const HvMessage *m);
+
+#endif // _HEAVY_SIGNAL_VAR_H_
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/projects/heavy/envelopeTrigger/Utils.h	Thu Nov 12 14:59:46 2015 +0000
@@ -0,0 +1,177 @@
+/**
+ * Copyright (c) 2014, 2015, Enzien Audio Ltd.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _HEAVY_UTILS_H_
+#define _HEAVY_UTILS_H_
+
+// Type definitions
+#if _WIN32 || _WIN64 || WINAPI_FAMILY
+#define HV_WIN 1
+#include <stddef.h>
+#if defined (_MSC_VER)
+#define HV_MSVC 1
+#endif
+#define hv_size_t unsigned long
+#define hv_uint32_t unsigned int
+#define hv_uint16_t unsigned short
+#define hv_int32_t int
+#elif __APPLE__ && __MACH__
+#define HV_APPLE 1
+#include <stddef.h>
+#define hv_size_t size_t
+#define hv_uint32_t unsigned int
+#define hv_uint16_t unsigned short
+#define hv_int32_t int
+#elif __unix__ || __unix
+#define HV_UNIX 1
+#include <stddef.h>
+#include <stdint.h>
+#define hv_size_t size_t
+#define hv_uint32_t uint32_t
+#define hv_uint16_t uint16_t
+#define hv_int32_t int32_t
+#else
+#error Unsupported platform
+#endif
+
+// Memory management
+extern void *hv_alloca(hv_size_t numbytes);
+extern void *hv_malloc(hv_size_t numbytes); // allocates memory on 16 byte boundaries and clears it to zero
+extern void hv_free(void *ptr); // frees aligned memory
+extern void *hv_realloc(void *ptr, hv_size_t numBytes);
+extern void *hv_memcpy(void *dest, const void *src, hv_size_t numbytes);
+extern void *hv_memset(void *ptr, hv_size_t numbytes); // sets everything to 0
+
+// String handling
+extern hv_size_t hv_strlen(const char *str);
+extern char *hv_strncat(char *dest, const char *str, hv_size_t n);
+extern char *hv_strncpy(char *dest, const char *str, hv_size_t n);
+extern int hv_strcmp(const char *str1, const char *str2);
+extern int hv_strncmp(const char *str1, const char *str2, hv_size_t n);
+extern int hv_snprintf(char *dest, hv_size_t n, const char *format, ...);
+
+// Math
+extern int hv_max_i(int x, int y);
+extern hv_size_t hv_max_ui(hv_size_t x, hv_size_t y);
+extern int hv_min_i(int x, int y);
+extern hv_size_t hv_min_ui(hv_size_t x, hv_size_t y);
+extern float hv_max_f(float x, float y);
+extern float hv_min_f(float x, float y);
+extern double hv_max_d(double x, double y);
+extern double hv_min_d(double x, double y);
+extern float hv_sin_f(float x);
+extern float hv_sinh_f(float x);
+extern float hv_cos_f(float x);
+extern float hv_cosh_f(float x);
+extern float hv_tan_f(float x);
+extern float hv_tanh_f(float x);
+extern float hv_asin_f(float x);
+extern float hv_asinh_f(float x);
+extern float hv_acos_f(float x);
+extern float hv_acosh_f(float x);
+extern float hv_atan_f(float x);
+extern float hv_atanh_f(float x);
+extern float hv_atan2_f(float x, float y);
+extern float hv_exp_f(float x);
+extern float hv_abs_f(float x);
+extern float hv_sqrt_f(float x);
+extern float hv_log_f(float x);
+extern float hv_log2_f(float x);
+extern float hv_log10_f(float x);
+extern float hv_ceil_f(float x);
+extern float hv_floor_f(float x);
+extern float hv_round_f(float x);
+extern float hv_pow_f(float x, float y);
+extern float hv_fma_f(float x, float y, float z);
+
+// Utilities
+extern void hv_assert(int e);
+extern void hv_clear_buffer(float *b, int n);
+extern hv_uint32_t hv_min_max_log2(hv_uint32_t x);
+
+// SIMD
+#ifndef HV_SIMD_NONE
+  #define HV_SIMD_NEON __ARM_NEON__
+  #define HV_SIMD_SSE (__SSE__ && __SSE2__ && __SSE3__ && __SSSE3__ && __SSE4_1__)
+  #define HV_SIMD_AVX (__AVX__ && HV_SIMD_SSE) // it is required that if AVX exists then SSE will also be available
+  #define HV_SIMD_FMA __FMA__
+#endif
+
+#ifdef HV_WIN
+#include "Utils_windows.h"
+#elif HV_APPLE
+#include "Utils_mac.h"
+#elif HV_UNIX
+#include "Utils_unix.h"
+#else
+#error Unsupported platform
+#endif
+
+#if HV_SIMD_NEON // NEON
+  #define HV_N_SIMD 4
+  #define hv_bufferf_t float32x4_t
+  #define hv_bufferi_t int32x4_t
+  #define hv_bInf_t float32x4_t
+  #define hv_bOutf_t float32x4_t*
+  #define hv_bIni_t int32x4_t
+  #define hv_bOuti_t int32x4_t*
+  #define VIf(_x) (_x)
+  #define VOf(_x) (&_x)
+  #define VIi(_x) (_x)
+  #define VOi(_x) (&_x)
+#elif HV_SIMD_AVX // AVX
+  #define HV_N_SIMD 8
+  #define hv_bufferf_t __m256
+  #define hv_bufferi_t __m256i
+  #define hv_bInf_t __m256
+  #define hv_bOutf_t __m256*
+  #define hv_bIni_t __m256i
+  #define hv_bOuti_t __m256i*
+  #define VIf(_x) (_x)
+  #define VOf(_x) (&_x)
+  #define VIi(_x) (_x)
+  #define VOi(_x) (&_x)
+#elif HV_SIMD_SSE // SSE
+  #define HV_N_SIMD 4
+  #define hv_bufferf_t __m128
+  #define hv_bufferi_t __m128i
+  #define hv_bInf_t __m128
+  #define hv_bOutf_t __m128*
+  #define hv_bIni_t __m128i
+  #define hv_bOuti_t __m128i*
+  #define VIf(_x) (_x)
+  #define VOf(_x) (&_x)
+  #define VIi(_x) (_x)
+  #define VOi(_x) (&_x)
+#else // DEFAULT
+  #define HV_N_SIMD 1
+  #undef HV_SIMD_NONE
+  #define HV_SIMD_NONE 1
+  #define hv_bufferf_t float
+  #define hv_bufferi_t int
+  #define hv_bInf_t float
+  #define hv_bOutf_t float*
+  #define hv_bIni_t int
+  #define hv_bOuti_t int*
+  #define VIf(_x) (_x)
+  #define VOf(_x) (&_x)
+  #define VIi(_x) (_x)
+  #define VOi(_x) (&_x)
+#endif
+
+#define HV_N_SIMD_MASK (HV_N_SIMD-1)
+
+#endif // _HEAVY_UTILS_H_
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/projects/heavy/envelopeTrigger/Utils_mac.c	Thu Nov 12 14:59:46 2015 +0000
@@ -0,0 +1,43 @@
+/**
+ * Copyright (c) 2014, 2015, Enzien Audio Ltd.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "Utils_mac.h"
+
+#if HV_APPLE
+
+hv_size_t hv_max_ui(hv_size_t x, hv_size_t y) {
+  return (x >= y) ? x : y;
+}
+
+hv_size_t hv_min_ui(hv_size_t x, hv_size_t y) {
+  return (x <= y) ? x : y;
+}
+
+int hv_max_i(int x, int y) {
+  return (x >= y) ? x : y;
+}
+
+int hv_min_i(int x, int y) {
+  return (x <= y) ? x : y;
+}
+
+hv_uint32_t hv_min_max_log2(hv_uint32_t x) {
+  // finds ceil(log2(x))
+  // http://stackoverflow.com/questions/2589096/find-most-significant-bit-left-most-that-is-set-in-a-bit-array
+  return (hv_uint32_t) ((8 * sizeof(unsigned int)) - __builtin_clz(x - 1));
+}
+
+#endif // HV_APPLE
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/projects/heavy/envelopeTrigger/Utils_mac.h	Thu Nov 12 14:59:46 2015 +0000
@@ -0,0 +1,98 @@
+/**
+ * Copyright (c) 2014, 2015, Enzien Audio Ltd.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _HEAVY_UTILS_MAC_H_
+#define _HEAVY_UTILS_MAC_H_
+
+#include "Utils.h"
+
+#if HV_APPLE
+#include <alloca.h>
+#if HV_SIMD_AVX || HV_SIMD_SSE
+#include <immintrin.h>
+#include <mm_malloc.h>
+#elif HV_SIMD_NEON
+#include <arm_neon.h>
+#endif
+#include <assert.h>
+#include <math.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define HV_EXPORT
+#define HV_FORCE_INLINE inline __attribute__((always_inline))
+
+// Memory management
+#define hv_alloca(_n) alloca(_n)
+#if HV_SIMD_AVX || HV_SIMD_SSE
+  #define hv_malloc(_n) _mm_malloc(_n, 32) // 32 to ensure AVX compatability (16 otherwise)
+  #define hv_free(x) _mm_free(x)
+#else
+  #define hv_malloc(_n) malloc(_n)
+  #define hv_free(x) free(x)
+#endif
+#define hv_realloc(a, b) realloc(a, b)
+#define hv_memcpy(a, b, c) memcpy(a, b, c)
+#define hv_memset(a, b) memset(a, 0, b)
+
+// Strings
+#define hv_strlen(a) strlen(a)
+#define hv_strncat(a, b, c) strncat(a, b, c)
+#define hv_strncpy(a, b, c) strncpy(a, b, c)
+#define hv_strcmp(a, b) strcmp(a, b)
+#define hv_strncmp(a, b, c) strncmp(a, b, c)
+#define hv_snprintf(a, b, c, ...) snprintf(a, b, c, __VA_ARGS__)
+
+// Math
+#define hv_max_f(a, b) fmaxf(a, b)
+#define hv_min_f(a, b) fminf(a, b)
+#define hv_max_d(a, b) fmax(a, b)
+#define hv_min_d(a, b) fmin(a, b)
+#define hv_sin_f(a) sinf(a)
+#define hv_sinh_f(a) sinhf(a)
+#define hv_cos_f(a) cosf(a)
+#define hv_cosh_f(a) coshf(a)
+#define hv_tan_f(a) tanf(a)
+#define hv_tanh_f(a) tanhf(a)
+#define hv_asin_f(a) asinf(a)
+#define hv_asinh_f(a) asinhf(a)
+#define hv_acos_f(a) acosf(a)
+#define hv_acosh_f(a) acoshf(a)
+#define hv_atan_f(a) atanf(a)
+#define hv_atanh_f(a) atanhf(a)
+#define hv_atan2_f(a, b) atan2f(a, b)
+#define hv_exp_f(a) expf(a)
+#define hv_abs_f(a) fabsf(a)
+#define hv_sqrt_f(a) sqrtf(a)
+#define hv_log_f(a) logf(a)
+#define hv_log2_f(a) log2f(a)
+#define hv_log10_f(a) log10f(a)
+#define hv_ceil_f(a) ceilf(a)
+#define hv_floor_f(a) floorf(a)
+#define hv_round_f(a) roundf(a)
+#define hv_pow_f(a, b) powf(a, b)
+#define hv_fma_f(a, b, c) ((a*b)+c) // TODO(joe): use 'fmaf(a, b, c)' once emscripten supports it
+
+// Utilities
+#define hv_assert(e) assert(e)
+#define hv_clear_buffer(b, n) memset(b, 0, (n)*sizeof(float))
+
+#endif // HV_APPLE
+#endif // _HEAVY_UTILS_MAC_H_
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/projects/heavy/envelopeTrigger/Utils_unix.c	Thu Nov 12 14:59:46 2015 +0000
@@ -0,0 +1,43 @@
+/**
+ * Copyright (c) 2014, 2015, Enzien Audio Ltd.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "Utils_unix.h"
+
+#if HV_UNIX
+
+hv_size_t hv_max_ui(hv_size_t x, hv_size_t y) {
+  return (x >= y) ? x : y;
+}
+
+hv_size_t hv_min_ui(hv_size_t x, hv_size_t y) {
+  return (x <= y) ? x : y;
+}
+
+int hv_max_i(int x, int y) {
+  return (x >= y) ? x : y;
+}
+
+int hv_min_i(int x, int y) {
+  return (x <= y) ? x : y;
+}
+
+hv_uint32_t hv_min_max_log2(hv_uint32_t x) {
+  // finds ceil(log2(x))
+  // http://stackoverflow.com/questions/2589096/find-most-significant-bit-left-most-that-is-set-in-a-bit-array
+  return (hv_uint32_t) ((8 * sizeof(unsigned int)) - __builtin_clz(x - 1));
+}
+
+#endif // HV_UNIX
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/projects/heavy/envelopeTrigger/Utils_unix.h	Thu Nov 12 14:59:46 2015 +0000
@@ -0,0 +1,98 @@
+/**
+ * Copyright (c) 2014, 2015, Enzien Audio Ltd.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _HEAVY_UTILS_UNIX_H_
+#define _HEAVY_UTILS_UNIX_H_
+
+#include "Utils.h"
+
+#if HV_UNIX
+#if HV_SIMD_AVX || HV_SIMD_SSE
+#include <immintrin.h>
+#include <mm_malloc.h>
+#elif HV_SIMD_NEON
+#include <arm_neon.h>
+#endif
+#include <alloca.h>
+#include <assert.h>
+#include <math.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define HV_EXPORT
+#define HV_FORCE_INLINE inline __attribute__((always_inline))
+
+// Memory management
+#define hv_alloca(_n) alloca(_n)
+#if HV_SIMD_AVX || HV_SIMD_SSE
+  #define hv_malloc(_n) _mm_malloc(_n, 32) // 32 to ensure AVX compatability (16 otherwise)
+  #define hv_free(x) _mm_free(x)
+#else
+  #define hv_malloc(_n) malloc(_n)
+  #define hv_free(_n) free(_n)
+#endif
+#define hv_realloc(a, b) realloc(a, b)
+#define hv_memcpy(a, b, c) memcpy(a, b, c)
+#define hv_memset(a, b) memset(a, 0, b)
+
+// Strings
+#define hv_strlen(a) strlen(a)
+#define hv_strncat(a, b, c) strncat(a, b, c)
+#define hv_strncpy(a, b, c) strncpy(a, b, c)
+#define hv_strcmp(a, b) strcmp(a, b)
+#define hv_strncmp(a, b, c) strncmp(a, b, c)
+#define hv_snprintf(a, b, c, ...) snprintf(a, b, c, __VA_ARGS__)
+
+// Math
+#define hv_max_f(a, b) fmaxf(a, b)
+#define hv_min_f(a, b) fminf(a, b)
+#define hv_max_d(a, b) fmax(a, b)
+#define hv_min_d(a, b) fmin(a, b)
+#define hv_sin_f(a) sinf(a)
+#define hv_sinh_f(a) sinhf(a)
+#define hv_cos_f(a) cosf(a)
+#define hv_cosh_f(a) coshf(a)
+#define hv_tan_f(a) tanf(a)
+#define hv_tanh_f(a) tanhf(a)
+#define hv_asin_f(a) asinf(a)
+#define hv_asinh_f(a) asinhf(a)
+#define hv_acos_f(a) acosf(a)
+#define hv_acosh_f(a) acoshf(a)
+#define hv_atan_f(a) atanf(a)
+#define hv_atanh_f(a) atanhf(a)
+#define hv_atan2_f(a, b) atan2f(a, b)
+#define hv_exp_f(a) expf(a)
+#define hv_abs_f(a) fabsf(a)
+#define hv_sqrt_f(a) sqrtf(a)
+#define hv_log_f(a) logf(a)
+#define hv_log2_f(a) log2f(a)
+#define hv_log10_f(a) log10f(a)
+#define hv_ceil_f(a) ceilf(a)
+#define hv_floor_f(a) floorf(a)
+#define hv_round_f(a) roundf(a)
+#define hv_pow_f(a, b) powf(a, b)
+#define hv_fma_f(a, b, c) ((a*b)+c) // TODO(joe): use 'fmaf(a, b, c)' once emscripten supports it
+
+// Utilities
+#define hv_assert(e) assert(e)
+#define hv_clear_buffer(b, n) memset(b, 0, n*sizeof(float))
+
+#endif // HV_UNIX
+#endif // _HEAVY_UTILS_UNIX_H_
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/projects/heavy/envelopeTrigger/Utils_windows.c	Thu Nov 12 14:59:46 2015 +0000
@@ -0,0 +1,68 @@
+/**
+ * Copyright (c) 2014, 2015, Enzien Audio Ltd.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "Utils_windows.h"
+
+#if HV_WIN
+
+hv_size_t hv_max_ui(hv_size_t x, hv_size_t y) {
+  return (x >= y) ? x : y;
+}
+
+hv_size_t hv_min_ui(hv_size_t x, hv_size_t y) {
+  return (x <= y) ? x : y;
+}
+
+int hv_max_i(int x, int y) {
+  return (x >= y) ? x : y;
+}
+
+int hv_min_i(int x, int y) {
+  return (x <= y) ? x : y;
+}
+
+hv_uint32_t hv_min_max_log2(hv_uint32_t x) {
+#if HV_MSVC
+  // finds ceil(log2(x))
+  // http://stackoverflow.com/questions/2589096/find-most-significant-bit-left-most-that-is-set-in-a-bit-array
+  // http://msdn.microsoft.com/en-us/library/fbxyd7zd%28v=VS.80%29.aspx
+  unsigned long z = 0;
+  _BitScanReverse(&z, x);
+  return (hv_uint32_t) (z+1);
+#else
+  return (hv_uint32_t) ((8 * sizeof(unsigned int)) - __builtin_clz(x-1));
+#endif // HV_MSVC
+}
+
+#if HV_MSVC
+int hv_snprintf(char* str, hv_size_t size, const char* format, ...) {
+  // http://stackoverflow.com/questions/2915672/snprintf-and-visual-studio-2010
+	int count = -1;
+	va_list ap;
+	va_start(ap, format);
+
+	if (size != 0) {
+		count = _vsnprintf_s(str, size, _TRUNCATE, format, ap);
+	}
+	if (count == -1) {
+		count = _vscprintf(format, ap);
+	}
+	va_end(ap);
+	return count;
+}
+#endif // HV_MSVC
+#endif // HV_WIN
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/projects/heavy/envelopeTrigger/Utils_windows.h	Thu Nov 12 14:59:46 2015 +0000
@@ -0,0 +1,109 @@
+/**
+ * Copyright (c) 2014, 2015, Enzien Audio Ltd.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _HEAVY_UTILS_WINDOWS_H_
+#define _HEAVY_UTILS_WINDOWS_H_
+
+#include "Utils.h"
+
+#if HV_WIN
+#define _USE_MATH_DEFINES
+#if HV_SIMD_AVX || HV_SIMD_SSE
+#if HV_MSVC
+#include <intrin.h>
+#else
+#include <immintrin.h>
+#endif
+#elif HV_SIMD_NEON
+#include <arm_neon.h>
+#endif
+#include <malloc.h>
+#include <assert.h>
+#include <math.h>
+#include <stdarg.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdbool.h>
+
+#define HV_EXPORT __declspec(dllexport)
+
+// MSVC Specific
+#if HV_MSVC
+#define inline __inline
+#define HV_FORCE_INLINE __forceinline
+#else
+#define HV_FORCE_INLINE inline __attribute__((always_inline))
+#define hv_snprintf(a, b, c, ...) snprintf(a, b, c, __VA_ARGS__)
+#endif // HV_MSVC
+
+// Memory management
+#define hv_alloca(_n) _alloca(_n)
+#if !defined(HV_SIMD_AVX) || !defined(HV_SIMD_SSE)
+#define hv_malloc(_n) _aligned_malloc(_n, 32)
+#define hv_free(x) _aligned_free(x)
+#else
+#define hv_malloc(_n) malloc(_n)
+#define hv_free(_n) free(_n)
+#endif
+#define hv_realloc(a, b) realloc(a, b)
+#define hv_memcpy(a, b, c) memcpy(a, b, c)
+#define hv_memset(a, b) memset(a, 0, b)
+
+// Strings
+#define hv_strncat(a, b, c) strncat(a, b, c)
+#define hv_strcmp(a, b) strcmp(a, b)
+#define hv_strncmp(a, b, c) strncmp(a, b, c)
+#define hv_strncpy(a, b, c) strncpy(a, b, c)
+#define hv_strlen(a) strlen(a)
+
+// Math
+#define hv_max_f(a, b) fmaxf(a, b)
+#define hv_min_f(a, b) fminf(a, b)
+#define hv_max_d(a, b) fmax(a, b)
+#define hv_min_d(a, b) fmin(a, b)
+#define hv_sin_f(a) sinf(a)
+#define hv_sinh_f(a) sinhf(a)
+#define hv_cos_f(a) cosf(a)
+#define hv_cosh_f(a) coshf(a)
+#define hv_tan_f(a) tanf(a)
+#define hv_tanh_f(a) tanhf(a)
+#define hv_asin_f(a) asinf(a)
+#define hv_asinh_f(a) asinhf(a)
+#define hv_acos_f(a) acosf(a)
+#define hv_acosh_f(a) acoshf(a)
+#define hv_atan_f(a) atanf(a)
+#define hv_atanh_f(a) atanhf(a)
+#define hv_atan2_f(a, b) atan2f(a, b)
+#define hv_exp_f(a) expf(a)
+#define hv_abs_f(a) fabsf(a)
+#define hv_sqrt_f(a) sqrtf(a)
+#define hv_log_f(a) logf(a)
+#define hv_log2_f(a) log2f(a)
+#define hv_log10_f(a) log10f(a)
+#define hv_ceil_f(a) ceilf(a)
+#define hv_floor_f(a) floorf(a)
+#define hv_round_f(a) roundf(a)
+#define hv_pow_f(a, b) powf(a, b)
+#define hv_fma_f(a, b, c) ((a*b)+c) // TODO(joe): use 'fmaf(a, b, c)' once emscripten supports it
+
+// Utilities
+#define hv_assert(e) assert(e)
+#define hv_clear_buffer(b, n) memset(b, 0, n*sizeof(float))
+
+#endif // HV_WIN
+#endif // _HEAVY_UTILS_WINDOWS_H_
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/projects/heavy/envelopeTrigger/render.cpp	Thu Nov 12 14:59:46 2015 +0000
@@ -0,0 +1,183 @@
+/*
+ * render.cpp
+ *
+ *  Template render.cpp file for on-board heavy compiling
+ *
+ *  N.B. this is currently *not* compatible with foleyDesigner source files!
+ *
+ *  Created on: November 5, 2015
+ *
+ *  Christian Heinrichs
+ *
+ */
+
+#include <BeagleRT.h>
+#include <cmath>
+#include "../include/Utilities.h"
+#include "Heavy_bbb.h"
+
+// #include "I2c_TouchKey.h"
+
+// #include "../include/UdpServer.h"
+// #include "../include/UdpClient.h"
+// #include <iostream>
+// #include <fstream>
+// #include "../include/ReceiveAudioThread.h"
+
+// #include "../include/render.h"
+// #include <arm_neon.h>
+// #include <time.h>
+// #include <sndfile.h>
+
+// #include "../include/RTAudio.h"
+// #include <rtdk.h>
+
+
+/*
+ *	HEAVY CONTEXT & BUFFERS
+ */
+
+Hv_bbb *gHeavyContext;
+float *gHvInputBuffers = NULL, *gHvOutputBuffers = NULL;
+int gHvInputChannels = 0, gHvOutputChannels = 0;
+
+float gInverseSampleRate;
+
+/*
+ *	HEAVY FUNCTIONS
+ */
+
+void printHook(double timestampSecs, const char *printLabel, const char *msgString, void *userData) {
+  printf("Message from Heavy patch: [@ %.3f] %s: %s\n", timestampSecs, printLabel, msgString);
+}
+
+static void sendHook(
+    double timestamp, // in milliseconds
+    const char *receiverName,
+    const HvMessage *const m,
+    void *userData) {
+
+  // only react to messages sent to receivers named "hello"
+  if (!strncmp(receiverName, "hello", 5)) {
+  }
+
+}
+
+/*
+ * RENDER INITIALISATION, LOOP & CLEANUP
+ */
+
+
+// bool initialise_render(int numMatrixChannels, int numAudioChannels,
+// 					   int numMatrixFramesPerPeriod,
+// 					   int numAudioFramesPerPeriod,
+// 					   float matrixSampleRate, float audioSampleRate,
+// 					   void *userData)
+// {
+bool setup(BeagleRTContext *context, void *userData)	{
+
+	/* HEAVY */
+
+	gHeavyContext = hv_bbb_new(context->audioSampleRate);
+
+	gHvInputChannels = hv_getNumInputChannels(gHeavyContext);
+	gHvOutputChannels = hv_getNumOutputChannels(gHeavyContext);
+
+	// srand ( time(NULL) );  	
+
+	rt_printf("Starting Heavy context with %d input channels and %d output channels\n",
+			  gHvInputChannels, gHvOutputChannels);
+
+	if(gHvInputChannels != 0) {
+		gHvInputBuffers = (float *)calloc(gHvInputChannels * context->audioFrames,sizeof(float));
+		//memset(gHvInputBuffers,0,gHvInputChannels * numAudioFramesPerPeriod * sizeof(float));
+	}
+	if(gHvOutputChannels != 0) {
+		gHvOutputBuffers = (float *)calloc(gHvOutputChannels * context->audioFrames,sizeof(float));
+	}
+
+	gInverseSampleRate = 1.0 / context->audioSampleRate;
+
+	// Set heavy print hook
+	hv_setPrintHook(gHeavyContext, &printHook);
+	// Set heavy send hook
+	hv_setSendHook(gHeavyContext, sendHook);
+
+	return true;
+}
+
+
+// void render(int numMatrixFrames, int numAudioFrames, float *audioIn, float *audioOut,
+// 			uint16_t *matrixIn, uint16_t *matrixOut)
+// {	
+void render(BeagleRTContext *context, void *userData)
+{
+	// use this for thread management
+	// if(gCount == 0) {
+	// } else {
+	// }
+	// gCount++;
+
+	// De-interleave the data
+	if(gHvInputBuffers != NULL) {
+		for(int n = 0; n < context->audioFrames; n++) {
+			for(int ch = 0; ch < gHvInputChannels; ch++) {
+				if(ch >= context->audioChannels+context->analogChannels) {
+					// THESE ARE PARAMETER INPUT 'CHANNELS' USED FOR ROUTING
+					// 'sensor' outputs from routing channels of dac~ are passed through here
+					break;
+				} else {
+					// If more than 2 ADC inputs are used in the pd patch, route the analog inputs
+					// i.e. ADC3->analogIn0 etc. (first two are always audio inputs)
+					if(ch >= context->audioChannels)	{
+						int m = n/2;
+						float mIn = context->analogIn[m*context->analogChannels + (ch-context->audioChannels)];
+						gHvInputBuffers[ch * context->audioFrames + n] = mIn;
+					} else {
+						gHvInputBuffers[ch * context->audioFrames + n] = context->audioIn[n * context->audioChannels + ch];
+					}
+				}
+			}
+		}
+	}
+
+	// replacement for bang~ object
+	//hv_vscheduleMessageForReceiver(gHeavyContext, "bbb_bang", 0.0f, "b");
+
+	hv_bbb_process_inline(gHeavyContext, gHvInputBuffers, gHvOutputBuffers, context->audioFrames);
+
+	// Interleave the output data
+	if(gHvOutputBuffers != NULL) {
+		for(int n = 0; n < context->audioFrames; n++) {
+
+			for(int ch = 0; ch < gHvOutputChannels; ch++) {
+				if(ch >= context->audioChannels+context->analogChannels) {
+					// THESE ARE SENSOR OUTPUT 'CHANNELS' USED FOR ROUTING
+					// they are the content of the 'sensor output' dac~ channels
+				} else {
+					if(ch >= context->audioChannels)	{
+						int m = n/2;
+						// float mOut = (float)gHvOutputBuffers[ch*numAudioFrames + n];
+						// mOut = constrain(mOut,0.0,1.0);
+						context->analogOut[m * context->analogFrames + (ch-context->audioChannels)] = constrain(gHvOutputBuffers[ch*context->audioFrames + n],0.0,1.0);
+					} else {
+						context->audioOut[n * context->audioChannels + ch] = gHvOutputBuffers[ch * context->audioFrames + n];
+					}
+				}
+			}
+		}
+	}
+
+}
+
+
+void cleanup(BeagleRTContext *context, void *userData)
+{
+
+	hv_bbb_free(gHeavyContext);
+	if(gHvInputBuffers != NULL)
+		free(gHvInputBuffers);
+	if(gHvOutputBuffers != NULL)
+		free(gHvOutputBuffers);
+
+}
--- a/projects/heavy/hello-world/HvContext_bbb.c	Thu Nov 05 19:27:44 2015 +0000
+++ b/projects/heavy/hello-world/HvContext_bbb.c	Thu Nov 12 14:59:46 2015 +0000
@@ -84,7 +84,7 @@
   Base(_c)->name = "bbb";
 
   Base(_c)->numBytes = sizeof(Hv_bbb);
-  Base(_c)->numBytes += sPhasor_k_init(&_c->sPhasor_O587H, 440.0f, sampleRate);
+  Base(_c)->numBytes += sPhasor_k_init(&_c->sPhasor_XIjUg, 440.0f, sampleRate);
 
   // loadbang
 
@@ -145,7 +145,7 @@
     __hv_zero_f(VOf(O1));
 
     // process all signal functions
-    __hv_phasor_k_f(&_c->sPhasor_O587H, VOf(Bf0));
+    __hv_phasor_k_f(&_c->sPhasor_XIjUg, VOf(Bf0));
     __hv_var_k_f(VOf(Bf1), 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0);
     __hv_sub_f(VIf(Bf0), VIf(Bf1), VOf(Bf1));
     __hv_abs_f(VIf(Bf1), VOf(Bf1));
@@ -163,8 +163,8 @@
     __hv_fma_f(VIf(Bf0), VIf(Bf3), VIf(Bf4), VOf(Bf4));
     __hv_var_k_f(VOf(Bf3), 0.1f, 0.1f, 0.1f, 0.1f, 0.1f, 0.1f, 0.1f, 0.1f, 0);
     __hv_mul_f(VIf(Bf4), VIf(Bf3), VOf(Bf3));
+    __hv_add_f(VIf(Bf3), VIf(O0), VOf(O0));
     __hv_add_f(VIf(Bf3), VIf(O1), VOf(O1));
-    __hv_add_f(VIf(Bf3), VIf(O0), VOf(O0));
 
     // save output vars to output buffer
     __hv_store_f(outputBuffers[0]+n, VIf(O0));
--- a/projects/heavy/hello-world/HvContext_bbb.h	Thu Nov 05 19:27:44 2015 +0000
+++ b/projects/heavy/hello-world/HvContext_bbb.h	Thu Nov 12 14:59:46 2015 +0000
@@ -40,7 +40,7 @@
   HvBase base;
 
   // objects
-  SignalPhasor sPhasor_O587H;
+  SignalPhasor sPhasor_XIjUg;
 } Hv_bbb;
 
 #endif // _HEAVYCONTEXT_BBB_H_
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/projects/heavy/pd/envelopeTrigger/_main.pd	Thu Nov 12 14:59:46 2015 +0000
@@ -0,0 +1,195 @@
+#N canvas 146 218 359 287 10;
+#X obj 28 207 dac~;
+#N canvas 324 380 556 621 env 0;
+#N canvas 886 1001 131 207 >~ 0;
+#X obj 19 -37 -~;
+#X obj 19 -58 min~;
+#X obj 19 26 *~ 1e+37;
+#X obj 19 5 +~ 1e-37;
+#X obj 19 -16 clip~ -1e-37 0;
+#X obj 19 -83 inlet~;
+#X obj 62 -83 inlet~;
+#X obj 19 48 outlet~;
+#X connect 0 0 4 0;
+#X connect 1 0 0 0;
+#X connect 2 0 7 0;
+#X connect 3 0 2 0;
+#X connect 4 0 3 0;
+#X connect 5 0 1 0;
+#X connect 6 0 0 1;
+#X connect 6 0 1 1;
+#X restore 199 106 pd >~;
+#X obj 23 173 /~ 44100;
+#X obj 68 153 samplerate~;
+#X obj 68 133 loadbang;
+#X obj 199 128 biquad~ 0 0 -1 1 0;
+#X obj 23 209 rpole~;
+#X obj 23 153 sig~ 1;
+#X obj 226 171 sig~ 0.5;
+#N canvas 0 22 110 231 <~ 0;
+#X obj 11 -41 -~;
+#X obj 11 29 +~ 1e-37;
+#X obj 11 8 clip~ -1e-37 0;
+#X obj 11 -86 inlet~;
+#X obj 55 -85 inlet~;
+#X obj 11 -62 max~;
+#X obj 11 -17 *~ -1;
+#X obj 11 81 outlet~;
+#X obj 11 50 *~ 1e+37;
+#X connect 0 0 6 0;
+#X connect 1 0 8 0;
+#X connect 2 0 1 0;
+#X connect 3 0 5 0;
+#X connect 4 0 0 1;
+#X connect 4 0 5 1;
+#X connect 5 0 0 0;
+#X connect 6 0 2 0;
+#X connect 8 0 7 0;
+#X restore 199 192 pd <~;
+#X text 237 193 (x != x);
+#X obj 23 447 *~;
+#X obj 199 150 *~ -1;
+#X obj 23 331 *~ 512;
+#X obj 23 229 clip~ 0 1;
+#X obj 23 390 tabread4~ env1;
+#X obj 23 310 *~;
+#X obj 199 64 abs~;
+#X obj 199 43 hip~ 1;
+#X obj 199 22 inlet~ excitationSignal;
+#X obj 218 269 sig~ 1;
+#X obj 218 292 /~;
+#X obj 226 86 inlet~ threshold;
+#X obj 262 229 inlet~ envDuration;
+#X obj 178 430 osc~ 220;
+#X obj 178 348 tabread4~ env1;
+#X obj 178 410 +~ 50;
+#X obj 178 370 *~;
+#X obj 178 390 *~ 1000;
+#X obj 262 269 clip~ 1e-05 100000;
+#X obj 23 467 outlet~;
+#N canvas 0 22 450 278 (subpatch) 0;
+#X array env1 512 float 3;
+#A 0 0 0.0625 0.0883883 0.108253 0.125 0.139754 0.153093 0.165359 0.176777
+0.1875 0.197642 0.207289 0.216506 0.225347 0.233854 0.242061 0.25 0.257694
+0.265165 0.272431 0.279509 0.286411 0.293151 0.299739 0.306186 0.3125
+0.318689 0.32476 0.330719 0.336573 0.342327 0.347985 0.353553 0.359035
+0.364434 0.369755 0.375 0.380173 0.385276 0.390312 0.395285 0.400195
+0.405046 0.40984 0.414578 0.419263 0.423896 0.428478 0.433013 0.4375
+0.441942 0.446339 0.450694 0.455007 0.459279 0.463512 0.467707 0.471865
+0.475986 0.480072 0.484123 0.488141 0.492125 0.496078 0.5 0.503891
+0.507752 0.511585 0.515388 0.519164 0.522913 0.526634 0.53033 0.534
+0.537645 0.541266 0.544862 0.548435 0.551985 0.555512 0.559017 0.5625
+0.565962 0.569402 0.572822 0.576222 0.579601 0.582961 0.586302 0.589624
+0.592927 0.596212 0.599479 0.602728 0.60596 0.609175 0.612372 0.615554
+0.618718 0.621867 0.625 0.628117 0.631219 0.634306 0.637377 0.640434
+0.643477 0.646505 0.649519 0.652519 0.655506 0.658478 0.661438 0.664384
+0.667317 0.670238 0.673146 0.676041 0.678924 0.681795 0.684653 0.6875
+0.690335 0.693159 0.695971 0.698771 0.701561 0.704339 0.707107 0.709864
+0.71261 0.715345 0.71807 0.720785 0.72349 0.726184 0.728869 0.731544
+0.734209 0.736864 0.73951 0.742146 0.744773 0.747391 0.75 0.7526 0.75519
+0.757772 0.760345 0.76291 0.765466 0.768013 0.770552 0.773082 0.775605
+0.778119 0.780625 0.783123 0.785613 0.788095 0.790569 0.793036 0.795495
+0.797947 0.800391 0.802827 0.805256 0.807678 0.810093 0.8125 0.8149
+0.817294 0.81968 0.822059 0.824432 0.826797 0.829156 0.831508 0.833854
+0.836193 0.838525 0.840851 0.843171 0.845484 0.847791 0.850092 0.852386
+0.854675 0.856957 0.859233 0.861503 0.863767 0.866025 0.868278 0.870524
+0.872765 0.875 0.877229 0.879453 0.881671 0.883883 0.88609 0.888292
+0.890488 0.892679 0.894864 0.897044 0.899218 0.901388 0.903552 0.905711
+0.907865 0.910014 0.912157 0.914296 0.91643 0.918559 0.920682 0.922801
+0.924916 0.927025 0.929129 0.931229 0.933324 0.935414 0.9375 0.939581
+0.941657 0.943729 0.945797 0.947859 0.949918 0.951972 0.954021 0.956066
+0.958107 0.960143 0.962175 0.964203 0.966227 0.968246 0.970261 0.972272
+0.974279 0.976281 0.97828 0.980274 0.982265 0.984251 0.986233 0.988212
+0.990186 0.992157 0.994123 0.996086 0.998045 1 0.992172 0.984375 0.976609
+0.968874 0.961169 0.953495 0.945852 0.938239 0.930657 0.923106 0.915586
+0.908097 0.900638 0.89321 0.885813 0.878447 0.871111 0.863806 0.856532
+0.849289 0.842076 0.834894 0.827743 0.820623 0.813533 0.806474 0.799446
+0.792449 0.785483 0.778547 0.771642 0.764767 0.757924 0.751111 0.744329
+0.737578 0.730857 0.724168 0.717509 0.71088 0.704283 0.697716 0.69118
+0.684675 0.678201 0.671757 0.665344 0.658962 0.652611 0.64629 0.64
+0.633741 0.627513 0.621315 0.615148 0.609012 0.602907 0.596832 0.590788
+0.584775 0.578793 0.572841 0.56692 0.56103 0.555171 0.549343 0.543545
+0.537778 0.532041 0.526336 0.520661 0.515017 0.509404 0.503822 0.49827
+0.492749 0.487259 0.481799 0.476371 0.470973 0.465605 0.460269 0.454963
+0.449689 0.444444 0.439231 0.434048 0.428897 0.423775 0.418685 0.413625
+0.408597 0.403599 0.398631 0.393695 0.388789 0.383914 0.37907 0.374256
+0.369473 0.364721 0.36 0.355309 0.35065 0.346021 0.341423 0.336855
+0.332318 0.327812 0.323337 0.318893 0.314479 0.310096 0.305744 0.301423
+0.297132 0.292872 0.288643 0.284444 0.280277 0.27614 0.272034 0.267958
+0.263914 0.2599 0.255917 0.251965 0.248043 0.244152 0.240292 0.236463
+0.232664 0.228897 0.22516 0.221453 0.217778 0.214133 0.210519 0.206936
+0.203383 0.199862 0.196371 0.19291 0.189481 0.186082 0.182714 0.179377
+0.176071 0.172795 0.16955 0.166336 0.163153 0.16 0.156878 0.153787
+0.150727 0.147697 0.144698 0.14173 0.138793 0.135886 0.13301 0.130165
+0.127351 0.124567 0.121815 0.119093 0.116401 0.113741 0.111111 0.108512
+0.105944 0.103406 0.1009 0.0984237 0.0959785 0.093564 0.0911803 0.0888274
+0.0865052 0.0842138 0.0819531 0.0797232 0.077524 0.0753556 0.073218
+0.0711111 0.069035 0.0669896 0.064975 0.0629911 0.0610381 0.0591157
+0.0572241 0.0553633 0.0535332 0.0517339 0.0499654 0.0482276 0.0465206
+0.0448443 0.0431988 0.041584 0.04 0.0384467 0.0369243 0.0354325 0.0339715
+0.0325413 0.0311419 0.0297732 0.0284352 0.027128 0.0258516 0.0246059
+0.023391 0.0222068 0.0210534 0.0199308 0.0188389 0.0177778 0.0167474
+0.0157478 0.0147789 0.0138408 0.0129335 0.0120569 0.0112111 0.010396
+0.00961169 0.00885813 0.00813533 0.00744329 0.00678201 0.00615148 0.00555171
+0.0049827 0.00444444 0.00393695 0.00346021 0.00301423 0.002599 0.00221453
+0.00186082 0.00153787 0.00124567 0.000984237 0.000753556 0.000553633
+0.000384467 0.000246059 0.000138408 6.15148e-05 1.53787e-05 0;
+#X coords 0 1 512 0 512 64 1 0 0;
+#X restore 24 516 graph;
+#X text 244 55 centre signal around zero and take abs value;
+#X text 243 107 if greater than threshold output 1;
+#X text 313 129 differentiator;
+#X text 238 150 (generates impulse on positive trigger (0->1);
+#X text 67 210 signal-rate counter;
+#X text 296 193 -> resets counter by briefly setting;
+#X text 314 204 rpole~ coeff to 0;
+#X text 246 391 kickdrum 101 :P;
+#X text 400 494 pre-generated envelope;
+#X obj 262 249 *~;
+#X connect 0 0 4 0;
+#X connect 1 0 5 0;
+#X connect 2 0 1 1;
+#X connect 3 0 2 0;
+#X connect 4 0 11 0;
+#X connect 5 0 13 0;
+#X connect 6 0 1 0;
+#X connect 7 0 8 1;
+#X connect 8 0 5 1;
+#X connect 10 0 29 0;
+#X connect 11 0 8 0;
+#X connect 12 0 14 0;
+#X connect 12 0 24 0;
+#X connect 13 0 15 0;
+#X connect 14 0 10 0;
+#X connect 15 0 12 0;
+#X connect 16 0 0 0;
+#X connect 17 0 16 0;
+#X connect 18 0 17 0;
+#X connect 19 0 20 0;
+#X connect 20 0 15 1;
+#X connect 21 0 0 1;
+#X connect 22 0 40 0;
+#X connect 22 0 40 1;
+#X connect 23 0 10 1;
+#X connect 24 0 26 0;
+#X connect 24 0 26 1;
+#X connect 25 0 23 0;
+#X connect 26 0 27 0;
+#X connect 27 0 25 0;
+#X connect 28 0 20 1;
+#X connect 40 0 28 0;
+#X restore 28 174 pd env;
+#X obj 79 110 adc~ 9;
+#X obj 129 130 adc~ 10;
+#X obj 28 90 adc~ 8;
+#X text 72 90 piezo input for excitation;
+#X text 123 110 fader 1 sets threshold;
+#X text 183 130 fader 2 sets duration;
+#X text 29 17 SAMPLE-ACCURATE ENVELOPE TRIGGER;
+#X text 29 27 ================================;
+#X text 142 259 @krighxz / BELA / heavy / 11/2015;
+#X connect 1 0 0 0;
+#X connect 1 0 0 1;
+#X connect 2 0 1 1;
+#X connect 3 0 1 2;
+#X connect 4 0 1 0;
--- a/projects/heavy/samphold/HvContext_bbb.c	Thu Nov 05 19:27:44 2015 +0000
+++ b/projects/heavy/samphold/HvContext_bbb.c	Thu Nov 12 14:59:46 2015 +0000
@@ -39,21 +39,21 @@
 /*
  * Function Declarations
  */
-static void cBinop_62MLs_sendMessage(HvBase *, int, const HvMessage *const);
-static void cUnop_Rm4T9_sendMessage(HvBase *, int, const HvMessage *const);
-static void cRandom_Uxs9y_sendMessage(HvBase *, int, const HvMessage *const);
-static void cLoadbang_XJMP6_sendMessage(HvBase *, int, const HvMessage *const);
-static void cMsg_eMw6t_sendMessage(HvBase *, int, const HvMessage *const);
-static void cBinop_vHnCM_sendMessage(HvBase *, int, const HvMessage *const);
-static void cBinop_PmuD1_sendMessage(HvBase *, int, const HvMessage *const);
-static void cBinop_lT4qw_sendMessage(HvBase *, int, const HvMessage *const);
-static void cBinop_vpZDi_sendMessage(HvBase *, int, const HvMessage *const);
-static void cMsg_zpcIL_sendMessage(HvBase *, int, const HvMessage *const);
-static void cMsg_pfnj7_sendMessage(HvBase *, int, const HvMessage *const);
-static void cSystem_lJZJR_sendMessage(HvBase *, int, const HvMessage *const);
-static void cVar_cPxQc_sendMessage(HvBase *, int, const HvMessage *const);
-static void cBinop_1u9M5_sendMessage(HvBase *, int, const HvMessage *const);
-static void cLoadbang_AXnu9_sendMessage(HvBase *, int, const HvMessage *const);
+static void cMsg_5KHpJ_sendMessage(HvBase *, int, const HvMessage *const);
+static void cSystem_tEzb9_sendMessage(HvBase *, int, const HvMessage *const);
+static void cBinop_DXD3m_sendMessage(HvBase *, int, const HvMessage *const);
+static void cBinop_tyjup_sendMessage(HvBase *, int, const HvMessage *const);
+static void cMsg_QrCwu_sendMessage(HvBase *, int, const HvMessage *const);
+static void cBinop_iWcBL_sendMessage(HvBase *, int, const HvMessage *const);
+static void cBinop_6USpC_sendMessage(HvBase *, int, const HvMessage *const);
+static void cBinop_QuDfQ_sendMessage(HvBase *, int, const HvMessage *const);
+static void cLoadbang_0Dgs1_sendMessage(HvBase *, int, const HvMessage *const);
+static void cVar_lxt7X_sendMessage(HvBase *, int, const HvMessage *const);
+static void cMsg_qW1tH_sendMessage(HvBase *, int, const HvMessage *const);
+static void cLoadbang_bGFum_sendMessage(HvBase *, int, const HvMessage *const);
+static void cBinop_79eIJ_sendMessage(HvBase *, int, const HvMessage *const);
+static void cRandom_zn9Go_sendMessage(HvBase *, int, const HvMessage *const);
+static void cUnop_2Y2rq_sendMessage(HvBase *, int, const HvMessage *const);
 
 
 
@@ -99,24 +99,24 @@
   Base(_c)->name = "bbb";
 
   Base(_c)->numBytes = sizeof(Hv_bbb);
-  Base(_c)->numBytes += sVari_init(&_c->sVari_ecpIx, 0, 0, false);
-  Base(_c)->numBytes += sVarf_init(&_c->sVarf_VF9rD, 0.0f, 0.0f, false);
-  Base(_c)->numBytes += sVarf_init(&_c->sVarf_0bFmM, 0.0f, 0.0f, false);
-  Base(_c)->numBytes += sRPole_init(&_c->sRPole_WxgWS);
-  Base(_c)->numBytes += sPhasor_k_init(&_c->sPhasor_YcHM3, 880.0f, sampleRate);
-  Base(_c)->numBytes += sDel1_init(&_c->sDel1_FfVih);
-  Base(_c)->numBytes += sSamphold_init(&_c->sSamphold_hq9sm);
-  Base(_c)->numBytes += sPhasor_init(&_c->sPhasor_n1TcS, sampleRate);
-  Base(_c)->numBytes += cBinop_init(&_c->cBinop_62MLs, 8388610.0f); // __mul
-  Base(_c)->numBytes += cRandom_init(&_c->cRandom_Uxs9y, -1512500956);
-  Base(_c)->numBytes += cBinop_init(&_c->cBinop_vHnCM, 1.0f); // __min
-  Base(_c)->numBytes += cBinop_init(&_c->cBinop_PmuD1, 0.0f); // __max
-  Base(_c)->numBytes += cBinop_init(&_c->cBinop_lT4qw, 0.0f); // __mul
-  Base(_c)->numBytes += cVar_init_f(&_c->cVar_cPxQc, 1.0f);
+  Base(_c)->numBytes += sVari_init(&_c->sVari_9lqOg, 0, 0, false);
+  Base(_c)->numBytes += sVarf_init(&_c->sVarf_a6sNx, 0.0f, 0.0f, false);
+  Base(_c)->numBytes += sVarf_init(&_c->sVarf_l59CR, 0.0f, 0.0f, false);
+  Base(_c)->numBytes += sRPole_init(&_c->sRPole_ACVjc);
+  Base(_c)->numBytes += sPhasor_k_init(&_c->sPhasor_GKtI5, 880.0f, sampleRate);
+  Base(_c)->numBytes += sDel1_init(&_c->sDel1_OZ8Kl);
+  Base(_c)->numBytes += sSamphold_init(&_c->sSamphold_XcpkT);
+  Base(_c)->numBytes += sPhasor_init(&_c->sPhasor_6rvdw, sampleRate);
+  Base(_c)->numBytes += cBinop_init(&_c->cBinop_tyjup, 0.0f); // __mul
+  Base(_c)->numBytes += cBinop_init(&_c->cBinop_iWcBL, 0.0f); // __max
+  Base(_c)->numBytes += cBinop_init(&_c->cBinop_6USpC, 1.0f); // __min
+  Base(_c)->numBytes += cVar_init_f(&_c->cVar_lxt7X, 1.0f);
+  Base(_c)->numBytes += cBinop_init(&_c->cBinop_79eIJ, 8388610.0f); // __mul
+  Base(_c)->numBytes += cRandom_init(&_c->cRandom_zn9Go, 1159211063);
 
   // loadbang
-  ctx_scheduleMessage(Base(_c), msg_initWithBang(HV_MESSAGE_ON_STACK(1), 0), &cLoadbang_AXnu9_sendMessage, 0);
-  ctx_scheduleMessage(Base(_c), msg_initWithBang(HV_MESSAGE_ON_STACK(1), 0), &cLoadbang_XJMP6_sendMessage, 0);
+  ctx_scheduleMessage(Base(_c), msg_initWithBang(HV_MESSAGE_ON_STACK(1), 0), &cLoadbang_0Dgs1_sendMessage, 0);
+  ctx_scheduleMessage(Base(_c), msg_initWithBang(HV_MESSAGE_ON_STACK(1), 0), &cLoadbang_bGFum_sendMessage, 0);
 
   return _c;
 }
@@ -138,80 +138,80 @@
 /*
  * Static Function Implementation
  */
-static void cBinop_62MLs_sendMessage(HvBase *_c, int letIn, const HvMessage *const m) {
-  cUnop_onMessage(_c, HV_UNOP_FLOOR, m, &cUnop_Rm4T9_sendMessage);
+static void cMsg_5KHpJ_sendMessage(HvBase *_c, int letIn, const HvMessage *const n) {
+  HvMessage *m = NULL;
+  m = HV_MESSAGE_ON_STACK(1);
+  msg_init(m, 1, msg_getTimestamp(n));
+  msg_setSymbol(m, 0, "samplerate");
+  cSystem_onMessage(_c, NULL, 0, m, &cSystem_tEzb9_sendMessage);
 }
 
-static void cUnop_Rm4T9_sendMessage(HvBase *_c, int letIn, const HvMessage *const m) {
-  cMsg_eMw6t_sendMessage(_c, 0, m);
+static void cSystem_tEzb9_sendMessage(HvBase *_c, int letIn, const HvMessage *const m) {
+  cMsg_QrCwu_sendMessage(_c, 0, m);
 }
 
-static void cRandom_Uxs9y_sendMessage(HvBase *_c, int letIn, const HvMessage *const m) {
-  cBinop_onMessage(_c, &Context(_c)->cBinop_62MLs, HV_BINOP_MULTIPLY, 0, m, &cBinop_62MLs_sendMessage);
+static void cBinop_DXD3m_sendMessage(HvBase *_c, int letIn, const HvMessage *const m) {
+  cBinop_onMessage(_c, &Context(_c)->cBinop_tyjup, HV_BINOP_MULTIPLY, 1, m, &cBinop_tyjup_sendMessage);
 }
 
-static void cLoadbang_XJMP6_sendMessage(HvBase *_c, int letIn, const HvMessage *const m) {
-  cRandom_onMessage(_c, &Context(_c)->cRandom_Uxs9y, 0, m, &cRandom_Uxs9y_sendMessage);
+static void cBinop_tyjup_sendMessage(HvBase *_c, int letIn, const HvMessage *const m) {
+  cBinop_onMessage(_c, &Context(_c)->cBinop_6USpC, HV_BINOP_MIN, 0, m, &cBinop_6USpC_sendMessage);
 }
 
-static void cMsg_eMw6t_sendMessage(HvBase *_c, int letIn, const HvMessage *const n) {
+static void cMsg_QrCwu_sendMessage(HvBase *_c, int letIn, const HvMessage *const n) {
+  HvMessage *m = NULL;
+  m = HV_MESSAGE_ON_STACK(2);
+  msg_init(m, 2, msg_getTimestamp(n));
+  msg_setFloat(m, 0, 6.28319f);
+  msg_setElementToFrom(m, 1, n, 0);
+  cBinop_k_onMessage(_c, NULL, HV_BINOP_DIVIDE, 0.0f, 0, m, &cBinop_DXD3m_sendMessage);
+}
+
+static void cBinop_iWcBL_sendMessage(HvBase *_c, int letIn, const HvMessage *const m) {
+  cBinop_k_onMessage(_c, NULL, HV_BINOP_SUBTRACT, 1.0f, 0, m, &cBinop_QuDfQ_sendMessage);
+  sVarf_onMessage(_c, &Context(_c)->sVarf_a6sNx, m);
+}
+
+static void cBinop_6USpC_sendMessage(HvBase *_c, int letIn, const HvMessage *const m) {
+  cBinop_onMessage(_c, &Context(_c)->cBinop_iWcBL, HV_BINOP_MAX, 0, m, &cBinop_iWcBL_sendMessage);
+}
+
+static void cBinop_QuDfQ_sendMessage(HvBase *_c, int letIn, const HvMessage *const m) {
+  sVarf_onMessage(_c, &Context(_c)->sVarf_l59CR, m);
+}
+
+static void cLoadbang_0Dgs1_sendMessage(HvBase *_c, int letIn, const HvMessage *const m) {
+  cMsg_5KHpJ_sendMessage(_c, 0, m);
+  cVar_onMessage(_c, &Context(_c)->cVar_lxt7X, 0, m, &cVar_lxt7X_sendMessage);
+}
+
+static void cVar_lxt7X_sendMessage(HvBase *_c, int letIn, const HvMessage *const m) {
+  cBinop_onMessage(_c, &Context(_c)->cBinop_tyjup, HV_BINOP_MULTIPLY, 0, m, &cBinop_tyjup_sendMessage);
+}
+
+static void cMsg_qW1tH_sendMessage(HvBase *_c, int letIn, const HvMessage *const n) {
   HvMessage *m = NULL;
   m = HV_MESSAGE_ON_STACK(2);
   msg_init(m, 2, msg_getTimestamp(n));
   msg_setElementToFrom(m, 0, n, 0);
   msg_setFloat(m, 1, 1.0f);
-  sVari_onMessage(_c, &Context(_c)->sVari_ecpIx, m);
+  sVari_onMessage(_c, &Context(_c)->sVari_9lqOg, m);
 }
 
-static void cBinop_vHnCM_sendMessage(HvBase *_c, int letIn, const HvMessage *const m) {
-  cBinop_onMessage(_c, &Context(_c)->cBinop_PmuD1, HV_BINOP_MAX, 0, m, &cBinop_PmuD1_sendMessage);
+static void cLoadbang_bGFum_sendMessage(HvBase *_c, int letIn, const HvMessage *const m) {
+  cRandom_onMessage(_c, &Context(_c)->cRandom_zn9Go, 0, m, &cRandom_zn9Go_sendMessage);
 }
 
-static void cBinop_PmuD1_sendMessage(HvBase *_c, int letIn, const HvMessage *const m) {
-  cBinop_k_onMessage(_c, NULL, HV_BINOP_SUBTRACT, 1.0f, 0, m, &cBinop_1u9M5_sendMessage);
-  sVarf_onMessage(_c, &Context(_c)->sVarf_VF9rD, m);
+static void cBinop_79eIJ_sendMessage(HvBase *_c, int letIn, const HvMessage *const m) {
+  cUnop_onMessage(_c, HV_UNOP_FLOOR, m, &cUnop_2Y2rq_sendMessage);
 }
 
-static void cBinop_lT4qw_sendMessage(HvBase *_c, int letIn, const HvMessage *const m) {
-  cBinop_onMessage(_c, &Context(_c)->cBinop_vHnCM, HV_BINOP_MIN, 0, m, &cBinop_vHnCM_sendMessage);
+static void cRandom_zn9Go_sendMessage(HvBase *_c, int letIn, const HvMessage *const m) {
+  cBinop_onMessage(_c, &Context(_c)->cBinop_79eIJ, HV_BINOP_MULTIPLY, 0, m, &cBinop_79eIJ_sendMessage);
 }
 
-static void cBinop_vpZDi_sendMessage(HvBase *_c, int letIn, const HvMessage *const m) {
-  cBinop_onMessage(_c, &Context(_c)->cBinop_lT4qw, HV_BINOP_MULTIPLY, 1, m, &cBinop_lT4qw_sendMessage);
-}
-
-static void cMsg_zpcIL_sendMessage(HvBase *_c, int letIn, const HvMessage *const n) {
-  HvMessage *m = NULL;
-  m = HV_MESSAGE_ON_STACK(2);
-  msg_init(m, 2, msg_getTimestamp(n));
-  msg_setFloat(m, 0, 6.28319f);
-  msg_setElementToFrom(m, 1, n, 0);
-  cBinop_k_onMessage(_c, NULL, HV_BINOP_DIVIDE, 0.0f, 0, m, &cBinop_vpZDi_sendMessage);
-}
-
-static void cMsg_pfnj7_sendMessage(HvBase *_c, int letIn, const HvMessage *const n) {
-  HvMessage *m = NULL;
-  m = HV_MESSAGE_ON_STACK(1);
-  msg_init(m, 1, msg_getTimestamp(n));
-  msg_setSymbol(m, 0, "samplerate");
-  cSystem_onMessage(_c, NULL, 0, m, &cSystem_lJZJR_sendMessage);
-}
-
-static void cSystem_lJZJR_sendMessage(HvBase *_c, int letIn, const HvMessage *const m) {
-  cMsg_zpcIL_sendMessage(_c, 0, m);
-}
-
-static void cVar_cPxQc_sendMessage(HvBase *_c, int letIn, const HvMessage *const m) {
-  cBinop_onMessage(_c, &Context(_c)->cBinop_lT4qw, HV_BINOP_MULTIPLY, 0, m, &cBinop_lT4qw_sendMessage);
-}
-
-static void cBinop_1u9M5_sendMessage(HvBase *_c, int letIn, const HvMessage *const m) {
-  sVarf_onMessage(_c, &Context(_c)->sVarf_0bFmM, m);
-}
-
-static void cLoadbang_AXnu9_sendMessage(HvBase *_c, int letIn, const HvMessage *const m) {
-  cMsg_pfnj7_sendMessage(_c, 0, m);
-  cVar_onMessage(_c, &Context(_c)->cVar_cPxQc, 0, m, &cVar_cPxQc_sendMessage);
+static void cUnop_2Y2rq_sendMessage(HvBase *_c, int letIn, const HvMessage *const m) {
+  cMsg_qW1tH_sendMessage(_c, 0, m);
 }
 
 
@@ -252,24 +252,24 @@
     __hv_zero_f(VOf(O1));
 
     // process all signal functions
-    __hv_var_i(&_c->sVari_ecpIx, VOi(Bi0));
+    __hv_var_i(&_c->sVari_9lqOg, VOi(Bi0));
     __hv_var_k_i(VOi(Bi1), 16807, 16807, 16807, 16807, 16807, 16807, 16807, 16807, 0);
     __hv_mul_i(VIi(Bi0), VIi(Bi1), VOi(Bi1));
+    sVarseti_process(&_c->sVari_9lqOg, VIi(Bi1));
     __hv_cast_if(VIi(Bi1), VOf(Bf0));
     __hv_var_k_f(VOf(Bf1), 4.65661e-10f, 4.65661e-10f, 4.65661e-10f, 4.65661e-10f, 4.65661e-10f, 4.65661e-10f, 4.65661e-10f, 4.65661e-10f, 0);
     __hv_mul_f(VIf(Bf0), VIf(Bf1), VOf(Bf1));
-    sVarseti_process(&_c->sVari_ecpIx, VIi(Bi1));
-    __hv_var_f(&_c->sVarf_VF9rD, VOf(Bf0));
+    __hv_var_f(&_c->sVarf_a6sNx, VOf(Bf0));
     __hv_mul_f(VIf(Bf1), VIf(Bf0), VOf(Bf0));
-    __hv_var_f(&_c->sVarf_0bFmM, VOf(Bf1));
-    __hv_rpole_f(&_c->sRPole_WxgWS, VIf(Bf0), VIf(Bf1), VOf(Bf1));
+    __hv_var_f(&_c->sVarf_l59CR, VOf(Bf1));
+    __hv_rpole_f(&_c->sRPole_ACVjc, VIf(Bf0), VIf(Bf1), VOf(Bf1));
     __hv_var_k_f(VOf(Bf0), 1000000.0f, 1000000.0f, 1000000.0f, 1000000.0f, 1000000.0f, 1000000.0f, 1000000.0f, 1000000.0f, 0);
     __hv_mul_f(VIf(Bf1), VIf(Bf0), VOf(Bf0));
-    __hv_phasor_k_f(&_c->sPhasor_YcHM3, VOf(Bf1));
-    __hv_del1_f(&_c->sDel1_FfVih, VIf(Bf1), VOf(Bf2));
+    __hv_phasor_k_f(&_c->sPhasor_GKtI5, VOf(Bf1));
+    __hv_del1_f(&_c->sDel1_OZ8Kl, VIf(Bf1), VOf(Bf2));
     __hv_lt_f(VIf(Bf1), VIf(Bf2), VOf(Bf2));
-    __hv_samphold_f(&_c->sSamphold_hq9sm, VIf(Bf0), VIf(Bf2), VOf(Bf2));
-    __hv_phasor_f(&_c->sPhasor_n1TcS, VIf(Bf2), VOf(Bf2));
+    __hv_samphold_f(&_c->sSamphold_XcpkT, VIf(Bf0), VIf(Bf2), VOf(Bf2));
+    __hv_phasor_f(&_c->sPhasor_6rvdw, VIf(Bf2), VOf(Bf2));
     __hv_var_k_f(VOf(Bf0), 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0);
     __hv_sub_f(VIf(Bf2), VIf(Bf0), VOf(Bf0));
     __hv_abs_f(VIf(Bf0), VOf(Bf0));
--- a/projects/heavy/samphold/HvContext_bbb.h	Thu Nov 05 19:27:44 2015 +0000
+++ b/projects/heavy/samphold/HvContext_bbb.h	Thu Nov 12 14:59:46 2015 +0000
@@ -48,22 +48,22 @@
   HvBase base;
 
   // objects
-  SignalVari sVari_ecpIx;
-  SignalVarf sVarf_VF9rD;
-  SignalVarf sVarf_0bFmM;
-  SignalRPole sRPole_WxgWS;
-  SignalPhasor sPhasor_YcHM3;
-  SignalDel1 sDel1_FfVih;
-  SignalSamphold sSamphold_hq9sm;
-  SignalPhasor sPhasor_n1TcS;
-  ControlBinop cBinop_62MLs;
-  ControlRandom cRandom_Uxs9y;
-  ControlBinop cBinop_vHnCM;
-  ControlBinop cBinop_PmuD1;
-  ControlBinop cBinop_lT4qw;
-  ControlBinop cBinop_vpZDi;
-  ControlVar cVar_cPxQc;
-  ControlBinop cBinop_1u9M5;
+  SignalVari sVari_9lqOg;
+  SignalVarf sVarf_a6sNx;
+  SignalVarf sVarf_l59CR;
+  SignalRPole sRPole_ACVjc;
+  SignalPhasor sPhasor_GKtI5;
+  SignalDel1 sDel1_OZ8Kl;
+  SignalSamphold sSamphold_XcpkT;
+  SignalPhasor sPhasor_6rvdw;
+  ControlBinop cBinop_DXD3m;
+  ControlBinop cBinop_tyjup;
+  ControlBinop cBinop_iWcBL;
+  ControlBinop cBinop_6USpC;
+  ControlBinop cBinop_QuDfQ;
+  ControlVar cVar_lxt7X;
+  ControlBinop cBinop_79eIJ;
+  ControlRandom cRandom_zn9Go;
 } Hv_bbb;
 
 #endif // _HEAVYCONTEXT_BBB_H_
--- a/scripts/build_pd.sh	Thu Nov 05 19:27:44 2015 +0000
+++ b/scripts/build_pd.sh	Thu Nov 12 14:59:46 2015 +0000
@@ -20,7 +20,7 @@
 function usage
 {
     echo "
-    USAGE: build_pd.sh [[-i input folder containing _main.pd file ] [-o output folder for new heavy project .c files (default ../projects/heavy/hvtemp)] [-r don't replace render.cpp file in destination project folder] [-b bbb path to copy to (default ~/BeagleRT)] | [-h]]
+    USAGE: build_pd.sh [[-i input folder containing _main.pd file ] [-o output folder for new heavy project .c files (default ../projects/heavy/hvtemp)] [-b bbb path to copy to (default ~/BeagleRT)] | [-h]]
     "    
     echo "example: build_pd.sh -i ../projects/heavy/pd/hello-world -o ../projects/heavy/hello-world"
 }
@@ -78,6 +78,9 @@
     exit 1;
 fi;
 
+# remove old executable and heavy context .o/.d files
+ssh $BBB_ADDRESS "rm $BBB_PATH/BeagleRT $BBB_PATH/build/source/HvContext_bbb.d $BBB_PATH/build/source/HvContext_bbb.o";
+
 # Make new BeagleRT executable and run
 if [ $RUN_PROJECT -eq 0 ]
 then