chris@160: chris@160: /** chris@160: * Copyright (c) 2014,2015 Enzien Audio, Ltd. chris@160: * chris@160: * Permission is hereby granted, free of charge, to any person obtaining a copy chris@160: * of this software and associated documentation files (the "Software"), chris@160: * to deal in the Software without restriction, including without limitation chris@160: * the rights to use, copy, modify, merge, publish, distribute, and/or chris@160: * sublicense copies of the Software, strictly on a non-commercial basis, chris@160: * and to permit persons to whom the Software is furnished to do so, chris@160: * subject to the following conditions: chris@160: * chris@160: * The above copyright notice and this permission notice shall be included in chris@160: * all copies or substantial portions of the Software. chris@160: * chris@160: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR chris@160: * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, chris@160: * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE chris@160: * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER chris@160: * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING chris@160: * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS chris@160: * IN THE SOFTWARE. chris@160: * chris@160: * DO NOT MODIFY. THIS CODE IS MACHINE GENERATED BY THE SECTION6 HEAVY COMPILER. chris@160: */ chris@160: chris@160: /* chris@160: * System Includes chris@160: */ chris@160: chris@160: #include chris@160: #include chris@160: #include chris@160: #include chris@160: #include "HvContext_bbb.h" chris@160: #include "HeavyMath.h" chris@160: chris@160: chris@160: /* chris@160: * Function Declarations chris@160: */ chris@162: static void cMsg_5KHpJ_sendMessage(HvBase *, int, const HvMessage *const); chris@162: static void cSystem_tEzb9_sendMessage(HvBase *, int, const HvMessage *const); chris@162: static void cBinop_DXD3m_sendMessage(HvBase *, int, const HvMessage *const); chris@162: static void cBinop_tyjup_sendMessage(HvBase *, int, const HvMessage *const); chris@162: static void cMsg_QrCwu_sendMessage(HvBase *, int, const HvMessage *const); chris@162: static void cBinop_iWcBL_sendMessage(HvBase *, int, const HvMessage *const); chris@162: static void cBinop_6USpC_sendMessage(HvBase *, int, const HvMessage *const); chris@162: static void cBinop_QuDfQ_sendMessage(HvBase *, int, const HvMessage *const); chris@162: static void cLoadbang_0Dgs1_sendMessage(HvBase *, int, const HvMessage *const); chris@162: static void cVar_lxt7X_sendMessage(HvBase *, int, const HvMessage *const); chris@162: static void cMsg_qW1tH_sendMessage(HvBase *, int, const HvMessage *const); chris@162: static void cLoadbang_bGFum_sendMessage(HvBase *, int, const HvMessage *const); chris@162: static void cBinop_79eIJ_sendMessage(HvBase *, int, const HvMessage *const); chris@162: static void cRandom_zn9Go_sendMessage(HvBase *, int, const HvMessage *const); chris@162: static void cUnop_2Y2rq_sendMessage(HvBase *, int, const HvMessage *const); chris@160: chris@160: chris@160: chris@160: /* chris@160: * Static Helper Functions chris@160: */ chris@160: chris@160: static void ctx_intern_scheduleMessageForReceiver( chris@160: HvBase *const _c, const char *name, HvMessage *m) { chris@160: switch (msg_symbolToHash(name)) { chris@160: default: return; chris@160: } chris@160: } chris@160: chris@160: static struct HvTable *ctx_intern_getTableForHash(HvBase *const _c, hv_uint32_t h) { chris@160: switch (h) { chris@160: default: return NULL; chris@160: } chris@160: } chris@160: chris@160: chris@160: chris@160: /* chris@160: * Context Include and Implementatons chris@160: */ chris@160: chris@160: Hv_bbb *hv_bbb_new_with_pool(double sampleRate, int poolKb) { chris@160: hv_assert(sampleRate > 0.0); // can't initialise with sampling rate of 0 chris@160: hv_assert(poolKb >= 1); // a message pool of some reasonable size is always needed chris@160: Hv_bbb *const _c = (Hv_bbb *) hv_malloc(sizeof(Hv_bbb)); chris@160: chris@160: Base(_c)->numInputChannels = 0; chris@160: Base(_c)->numOutputChannels = 2; chris@160: Base(_c)->sampleRate = sampleRate; chris@160: Base(_c)->blockStartTimestamp = 0; chris@160: Base(_c)->f_scheduleMessageForReceiver = &ctx_intern_scheduleMessageForReceiver; chris@160: Base(_c)->f_getTableForHash = &ctx_intern_getTableForHash; chris@160: mq_initWithPoolSize(&Base(_c)->mq, poolKb); chris@160: Base(_c)->basePath = NULL; chris@160: Base(_c)->printHook = NULL; chris@160: Base(_c)->sendHook = NULL; chris@160: Base(_c)->userData = NULL; chris@160: Base(_c)->name = "bbb"; chris@160: chris@160: Base(_c)->numBytes = sizeof(Hv_bbb); chris@162: Base(_c)->numBytes += sVari_init(&_c->sVari_9lqOg, 0, 0, false); chris@162: Base(_c)->numBytes += sVarf_init(&_c->sVarf_a6sNx, 0.0f, 0.0f, false); chris@162: Base(_c)->numBytes += sVarf_init(&_c->sVarf_l59CR, 0.0f, 0.0f, false); chris@162: Base(_c)->numBytes += sRPole_init(&_c->sRPole_ACVjc); chris@162: Base(_c)->numBytes += sPhasor_k_init(&_c->sPhasor_GKtI5, 880.0f, sampleRate); chris@162: Base(_c)->numBytes += sDel1_init(&_c->sDel1_OZ8Kl); chris@162: Base(_c)->numBytes += sSamphold_init(&_c->sSamphold_XcpkT); chris@162: Base(_c)->numBytes += sPhasor_init(&_c->sPhasor_6rvdw, sampleRate); chris@162: Base(_c)->numBytes += cBinop_init(&_c->cBinop_tyjup, 0.0f); // __mul chris@162: Base(_c)->numBytes += cBinop_init(&_c->cBinop_iWcBL, 0.0f); // __max chris@162: Base(_c)->numBytes += cBinop_init(&_c->cBinop_6USpC, 1.0f); // __min chris@162: Base(_c)->numBytes += cVar_init_f(&_c->cVar_lxt7X, 1.0f); chris@162: Base(_c)->numBytes += cBinop_init(&_c->cBinop_79eIJ, 8388610.0f); // __mul chris@162: Base(_c)->numBytes += cRandom_init(&_c->cRandom_zn9Go, 1159211063); chris@160: chris@160: // loadbang chris@162: ctx_scheduleMessage(Base(_c), msg_initWithBang(HV_MESSAGE_ON_STACK(1), 0), &cLoadbang_0Dgs1_sendMessage, 0); chris@162: ctx_scheduleMessage(Base(_c), msg_initWithBang(HV_MESSAGE_ON_STACK(1), 0), &cLoadbang_bGFum_sendMessage, 0); chris@160: chris@160: return _c; chris@160: } chris@160: chris@160: Hv_bbb *hv_bbb_new(double sampleRate) { chris@160: return hv_bbb_new_with_pool(sampleRate, 10); // default to 10KB MessagePool chris@160: } chris@160: chris@160: void hv_bbb_free(Hv_bbb *_c) { chris@160: chris@160: hv_free(Base(_c)->basePath); chris@160: mq_free(&Base(_c)->mq); // free queue after all objects have been freed, messages may be cancelled chris@160: chris@160: hv_free(_c); chris@160: } chris@160: chris@160: chris@160: chris@160: /* chris@160: * Static Function Implementation chris@160: */ chris@162: static void cMsg_5KHpJ_sendMessage(HvBase *_c, int letIn, const HvMessage *const n) { chris@162: HvMessage *m = NULL; chris@162: m = HV_MESSAGE_ON_STACK(1); chris@162: msg_init(m, 1, msg_getTimestamp(n)); chris@162: msg_setSymbol(m, 0, "samplerate"); chris@162: cSystem_onMessage(_c, NULL, 0, m, &cSystem_tEzb9_sendMessage); chris@160: } chris@160: chris@162: static void cSystem_tEzb9_sendMessage(HvBase *_c, int letIn, const HvMessage *const m) { chris@162: cMsg_QrCwu_sendMessage(_c, 0, m); chris@160: } chris@160: chris@162: static void cBinop_DXD3m_sendMessage(HvBase *_c, int letIn, const HvMessage *const m) { chris@162: cBinop_onMessage(_c, &Context(_c)->cBinop_tyjup, HV_BINOP_MULTIPLY, 1, m, &cBinop_tyjup_sendMessage); chris@160: } chris@160: chris@162: static void cBinop_tyjup_sendMessage(HvBase *_c, int letIn, const HvMessage *const m) { chris@162: cBinop_onMessage(_c, &Context(_c)->cBinop_6USpC, HV_BINOP_MIN, 0, m, &cBinop_6USpC_sendMessage); chris@160: } chris@160: chris@162: static void cMsg_QrCwu_sendMessage(HvBase *_c, int letIn, const HvMessage *const n) { chris@162: HvMessage *m = NULL; chris@162: m = HV_MESSAGE_ON_STACK(2); chris@162: msg_init(m, 2, msg_getTimestamp(n)); chris@162: msg_setFloat(m, 0, 6.28319f); chris@162: msg_setElementToFrom(m, 1, n, 0); chris@162: cBinop_k_onMessage(_c, NULL, HV_BINOP_DIVIDE, 0.0f, 0, m, &cBinop_DXD3m_sendMessage); chris@162: } chris@162: chris@162: static void cBinop_iWcBL_sendMessage(HvBase *_c, int letIn, const HvMessage *const m) { chris@162: cBinop_k_onMessage(_c, NULL, HV_BINOP_SUBTRACT, 1.0f, 0, m, &cBinop_QuDfQ_sendMessage); chris@162: sVarf_onMessage(_c, &Context(_c)->sVarf_a6sNx, m); chris@162: } chris@162: chris@162: static void cBinop_6USpC_sendMessage(HvBase *_c, int letIn, const HvMessage *const m) { chris@162: cBinop_onMessage(_c, &Context(_c)->cBinop_iWcBL, HV_BINOP_MAX, 0, m, &cBinop_iWcBL_sendMessage); chris@162: } chris@162: chris@162: static void cBinop_QuDfQ_sendMessage(HvBase *_c, int letIn, const HvMessage *const m) { chris@162: sVarf_onMessage(_c, &Context(_c)->sVarf_l59CR, m); chris@162: } chris@162: chris@162: static void cLoadbang_0Dgs1_sendMessage(HvBase *_c, int letIn, const HvMessage *const m) { chris@162: cMsg_5KHpJ_sendMessage(_c, 0, m); chris@162: cVar_onMessage(_c, &Context(_c)->cVar_lxt7X, 0, m, &cVar_lxt7X_sendMessage); chris@162: } chris@162: chris@162: static void cVar_lxt7X_sendMessage(HvBase *_c, int letIn, const HvMessage *const m) { chris@162: cBinop_onMessage(_c, &Context(_c)->cBinop_tyjup, HV_BINOP_MULTIPLY, 0, m, &cBinop_tyjup_sendMessage); chris@162: } chris@162: chris@162: static void cMsg_qW1tH_sendMessage(HvBase *_c, int letIn, const HvMessage *const n) { chris@160: HvMessage *m = NULL; chris@160: m = HV_MESSAGE_ON_STACK(2); chris@160: msg_init(m, 2, msg_getTimestamp(n)); chris@160: msg_setElementToFrom(m, 0, n, 0); chris@160: msg_setFloat(m, 1, 1.0f); chris@162: sVari_onMessage(_c, &Context(_c)->sVari_9lqOg, m); chris@160: } chris@160: chris@162: static void cLoadbang_bGFum_sendMessage(HvBase *_c, int letIn, const HvMessage *const m) { chris@162: cRandom_onMessage(_c, &Context(_c)->cRandom_zn9Go, 0, m, &cRandom_zn9Go_sendMessage); chris@160: } chris@160: chris@162: static void cBinop_79eIJ_sendMessage(HvBase *_c, int letIn, const HvMessage *const m) { chris@162: cUnop_onMessage(_c, HV_UNOP_FLOOR, m, &cUnop_2Y2rq_sendMessage); chris@160: } chris@160: chris@162: static void cRandom_zn9Go_sendMessage(HvBase *_c, int letIn, const HvMessage *const m) { chris@162: cBinop_onMessage(_c, &Context(_c)->cBinop_79eIJ, HV_BINOP_MULTIPLY, 0, m, &cBinop_79eIJ_sendMessage); chris@160: } chris@160: chris@162: static void cUnop_2Y2rq_sendMessage(HvBase *_c, int letIn, const HvMessage *const m) { chris@162: cMsg_qW1tH_sendMessage(_c, 0, m); chris@160: } chris@160: chris@160: chris@160: chris@160: chris@160: /* chris@160: * Context Process Implementation chris@160: */ chris@160: chris@160: int hv_bbb_process(Hv_bbb *const _c, float **const inputBuffers, float **const outputBuffers, int nx) { chris@160: const int n4 = nx & ~HV_N_SIMD_MASK; // ensure that the block size is a multiple of HV_N_SIMD chris@160: chris@160: // temporary signal vars chris@160: hv_bufferf_t Bf0, Bf1, Bf2, Bf3, Bf4; chris@160: hv_bufferi_t Bi0, Bi1; chris@160: chris@160: // input and output vars chris@160: hv_bufferf_t O0, O1; chris@160: chris@160: // declare and init the zero buffer chris@160: hv_bufferf_t ZERO; __hv_zero_f(VOf(ZERO)); chris@160: chris@160: hv_uint32_t nextBlock = Base(_c)->blockStartTimestamp; chris@160: for (int n = 0; n < n4; n += HV_N_SIMD) { chris@160: chris@160: // process all of the messages for this block chris@160: nextBlock += HV_N_SIMD; chris@160: while (mq_hasMessageBefore(&Base(_c)->mq, nextBlock)) { chris@160: MessageNode *const node = mq_peek(&Base(_c)->mq); chris@160: node->sendMessage(Base(_c), node->let, node->m); chris@160: mq_pop(&Base(_c)->mq); chris@160: } chris@160: chris@160: chris@160: chris@160: // zero output buffers chris@160: __hv_zero_f(VOf(O0)); chris@160: __hv_zero_f(VOf(O1)); chris@160: chris@160: // process all signal functions chris@162: __hv_var_i(&_c->sVari_9lqOg, VOi(Bi0)); chris@160: __hv_var_k_i(VOi(Bi1), 16807, 16807, 16807, 16807, 16807, 16807, 16807, 16807, 0); chris@160: __hv_mul_i(VIi(Bi0), VIi(Bi1), VOi(Bi1)); chris@162: sVarseti_process(&_c->sVari_9lqOg, VIi(Bi1)); chris@160: __hv_cast_if(VIi(Bi1), VOf(Bf0)); chris@160: __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); chris@160: __hv_mul_f(VIf(Bf0), VIf(Bf1), VOf(Bf1)); chris@162: __hv_var_f(&_c->sVarf_a6sNx, VOf(Bf0)); chris@160: __hv_mul_f(VIf(Bf1), VIf(Bf0), VOf(Bf0)); chris@162: __hv_var_f(&_c->sVarf_l59CR, VOf(Bf1)); chris@162: __hv_rpole_f(&_c->sRPole_ACVjc, VIf(Bf0), VIf(Bf1), VOf(Bf1)); chris@160: __hv_var_k_f(VOf(Bf0), 1000000.0f, 1000000.0f, 1000000.0f, 1000000.0f, 1000000.0f, 1000000.0f, 1000000.0f, 1000000.0f, 0); chris@160: __hv_mul_f(VIf(Bf1), VIf(Bf0), VOf(Bf0)); chris@162: __hv_phasor_k_f(&_c->sPhasor_GKtI5, VOf(Bf1)); chris@162: __hv_del1_f(&_c->sDel1_OZ8Kl, VIf(Bf1), VOf(Bf2)); chris@160: __hv_lt_f(VIf(Bf1), VIf(Bf2), VOf(Bf2)); chris@162: __hv_samphold_f(&_c->sSamphold_XcpkT, VIf(Bf0), VIf(Bf2), VOf(Bf2)); chris@162: __hv_phasor_f(&_c->sPhasor_6rvdw, VIf(Bf2), VOf(Bf2)); chris@160: __hv_var_k_f(VOf(Bf0), 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0); chris@160: __hv_sub_f(VIf(Bf2), VIf(Bf0), VOf(Bf0)); chris@160: __hv_abs_f(VIf(Bf0), VOf(Bf0)); chris@160: __hv_var_k_f(VOf(Bf2), 0.25f, 0.25f, 0.25f, 0.25f, 0.25f, 0.25f, 0.25f, 0.25f, 0); chris@160: __hv_sub_f(VIf(Bf0), VIf(Bf2), VOf(Bf2)); chris@160: __hv_var_k_f(VOf(Bf0), 6.28319f, 6.28319f, 6.28319f, 6.28319f, 6.28319f, 6.28319f, 6.28319f, 6.28319f, 0); chris@160: __hv_mul_f(VIf(Bf2), VIf(Bf0), VOf(Bf0)); chris@160: __hv_mul_f(VIf(Bf0), VIf(Bf0), VOf(Bf2)); chris@160: __hv_mul_f(VIf(Bf0), VIf(Bf2), VOf(Bf1)); chris@160: __hv_mul_f(VIf(Bf1), VIf(Bf2), VOf(Bf2)); chris@160: __hv_var_k_f(VOf(Bf3), 0.00784314f, 0.00784314f, 0.00784314f, 0.00784314f, 0.00784314f, 0.00784314f, 0.00784314f, 0.00784314f, 0); chris@160: __hv_var_k_f(VOf(Bf4), 0.166667f, 0.166667f, 0.166667f, 0.166667f, 0.166667f, 0.166667f, 0.166667f, 0.166667f, 0); chris@160: __hv_mul_f(VIf(Bf1), VIf(Bf4), VOf(Bf4)); chris@160: __hv_sub_f(VIf(Bf0), VIf(Bf4), VOf(Bf4)); chris@160: __hv_fma_f(VIf(Bf2), VIf(Bf3), VIf(Bf4), VOf(Bf4)); chris@160: __hv_var_k_f(VOf(Bf3), 0.1f, 0.1f, 0.1f, 0.1f, 0.1f, 0.1f, 0.1f, 0.1f, 0); chris@160: __hv_mul_f(VIf(Bf4), VIf(Bf3), VOf(Bf3)); chris@160: __hv_add_f(VIf(Bf3), VIf(O0), VOf(O0)); chris@160: __hv_add_f(VIf(Bf3), VIf(O1), VOf(O1)); chris@160: chris@160: // save output vars to output buffer chris@160: __hv_store_f(outputBuffers[0]+n, VIf(O0)); chris@160: __hv_store_f(outputBuffers[1]+n, VIf(O1)); chris@160: } chris@160: chris@160: Base(_c)->blockStartTimestamp = nextBlock; chris@160: chris@160: return n4; // return the number of frames processed chris@160: } chris@160: chris@160: int hv_bbb_process_inline(Hv_bbb *c, float *const inputBuffers, float *const outputBuffers, int n4) { chris@160: hv_assert(!(n4 & HV_N_SIMD_MASK)); // ensure that n4 is a multiple of HV_N_SIMD chris@160: int i = ctx_getNumInputChannels(Base(c)); chris@160: float **bIn = (float **) hv_alloca(i*sizeof(float *)); chris@160: while (i--) bIn[i] = inputBuffers+(i*n4); chris@160: chris@160: i = ctx_getNumOutputChannels(Base(c)); chris@160: float **bOut = (float **) hv_alloca(i*sizeof(float *)); chris@160: while (i--) bOut[i] = outputBuffers+(i*n4); chris@160: chris@160: int n = hv_bbb_process(c, bIn, bOut, n4); chris@160: return n; chris@160: } chris@160: chris@160: int hv_bbb_process_inline_short(Hv_bbb *c, short *const inputBuffers, short *const outputBuffers, int n4) { chris@160: hv_assert(!(n4 & HV_N_SIMD_MASK)); // ensure that n4 is a multiple of HV_N_SIMD chris@160: int numChannels = ctx_getNumInputChannels(Base(c)); chris@160: float *bIn = (float *) hv_alloca(numChannels*n4*sizeof(float)); chris@160: for (int i = 0; i < numChannels; ++i) { chris@160: for (int j = 0; j < n4; ++j) { chris@160: bIn[i*n4+j] = ((float) inputBuffers[i+numChannels*j]) * 0.00003051757813f; chris@160: } chris@160: } chris@160: chris@160: numChannels = ctx_getNumOutputChannels(Base(c)); chris@160: float *bOut = (float *) hv_alloca(numChannels*n4*sizeof(float)); chris@160: chris@160: int n = hv_bbb_process_inline(c, bIn, bOut, n4); chris@160: chris@160: for (int i = 0; i < numChannels; ++i) { chris@160: for (int j = 0; j < n4; ++j) { chris@160: outputBuffers[i+numChannels*j] = (short) (bOut[i*n4+j] * 32767.0f); chris@160: } chris@160: } chris@160: chris@160: return n; chris@160: }