Mercurial > hg > beaglert
diff projects/heavy/hello-world/HvContext_bbb.c @ 160:5bcf04234f80 heavy-updated
- added -std=c99 to Makefile for user-supplied C files (required for heavy files)
- changed heavy core render.cpp file to use latest API and removed all redundant functions (e.g. foleyDesigner/touchkey stuff)
- use build_pd.sh to compile and run pd files (-h for usage instructions)
author | chnrx <chris.heinrichs@gmail.com> |
---|---|
date | Thu, 05 Nov 2015 18:58:26 +0000 |
parents | |
children | c3e8226a5651 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/projects/heavy/hello-world/HvContext_bbb.c Thu Nov 05 18:58:26 2015 +0000 @@ -0,0 +1,215 @@ + +/** + * 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 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) { + 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 = 0; + 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 += sPhasor_k_init(&_c->sPhasor_O587H, 440.0f, sampleRate); + + // loadbang + + 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) { + + 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 + */ + + + +/* + * 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; + + // input and output vars + hv_bufferf_t O0, O1; + + // 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); + } + + + + // zero output buffers + __hv_zero_f(VOf(O0)); + __hv_zero_f(VOf(O1)); + + // process all signal functions + __hv_phasor_k_f(&_c->sPhasor_O587H, 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)); + __hv_var_k_f(VOf(Bf0), 0.25f, 0.25f, 0.25f, 0.25f, 0.25f, 0.25f, 0.25f, 0.25f, 0); + __hv_sub_f(VIf(Bf1), VIf(Bf0), VOf(Bf0)); + __hv_var_k_f(VOf(Bf1), 6.28319f, 6.28319f, 6.28319f, 6.28319f, 6.28319f, 6.28319f, 6.28319f, 6.28319f, 0); + __hv_mul_f(VIf(Bf0), VIf(Bf1), VOf(Bf1)); + __hv_mul_f(VIf(Bf1), VIf(Bf1), VOf(Bf0)); + __hv_mul_f(VIf(Bf1), VIf(Bf0), VOf(Bf2)); + __hv_mul_f(VIf(Bf2), VIf(Bf0), VOf(Bf0)); + __hv_var_k_f(VOf(Bf3), 0.00784314f, 0.00784314f, 0.00784314f, 0.00784314f, 0.00784314f, 0.00784314f, 0.00784314f, 0.00784314f, 0); + __hv_var_k_f(VOf(Bf4), 0.166667f, 0.166667f, 0.166667f, 0.166667f, 0.166667f, 0.166667f, 0.166667f, 0.166667f, 0); + __hv_mul_f(VIf(Bf2), VIf(Bf4), VOf(Bf4)); + __hv_sub_f(VIf(Bf1), VIf(Bf4), VOf(Bf4)); + __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(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)); + __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; +}