Mercurial > hg > beaglert
changeset 162:c3e8226a5651 heavy-updated
- added additional flags to C rules (-DNDEBUG, -mfpu=neon)
- sample-accurate envelope triggering pd/heavy example
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