annotate projects/heavy/envelopeTrigger/render.cpp @ 162:c3e8226a5651 heavy-updated

- added additional flags to C rules (-DNDEBUG, -mfpu=neon) - sample-accurate envelope triggering pd/heavy example
author chnrx <chris.heinrichs@gmail.com>
date Thu, 12 Nov 2015 14:59:46 +0000
parents
children
rev   line source
chris@162 1 /*
chris@162 2 * render.cpp
chris@162 3 *
chris@162 4 * Template render.cpp file for on-board heavy compiling
chris@162 5 *
chris@162 6 * N.B. this is currently *not* compatible with foleyDesigner source files!
chris@162 7 *
chris@162 8 * Created on: November 5, 2015
chris@162 9 *
chris@162 10 * Christian Heinrichs
chris@162 11 *
chris@162 12 */
chris@162 13
chris@162 14 #include <BeagleRT.h>
chris@162 15 #include <cmath>
chris@162 16 #include "../include/Utilities.h"
chris@162 17 #include "Heavy_bbb.h"
chris@162 18
chris@162 19 // #include "I2c_TouchKey.h"
chris@162 20
chris@162 21 // #include "../include/UdpServer.h"
chris@162 22 // #include "../include/UdpClient.h"
chris@162 23 // #include <iostream>
chris@162 24 // #include <fstream>
chris@162 25 // #include "../include/ReceiveAudioThread.h"
chris@162 26
chris@162 27 // #include "../include/render.h"
chris@162 28 // #include <arm_neon.h>
chris@162 29 // #include <time.h>
chris@162 30 // #include <sndfile.h>
chris@162 31
chris@162 32 // #include "../include/RTAudio.h"
chris@162 33 // #include <rtdk.h>
chris@162 34
chris@162 35
chris@162 36 /*
chris@162 37 * HEAVY CONTEXT & BUFFERS
chris@162 38 */
chris@162 39
chris@162 40 Hv_bbb *gHeavyContext;
chris@162 41 float *gHvInputBuffers = NULL, *gHvOutputBuffers = NULL;
chris@162 42 int gHvInputChannels = 0, gHvOutputChannels = 0;
chris@162 43
chris@162 44 float gInverseSampleRate;
chris@162 45
chris@162 46 /*
chris@162 47 * HEAVY FUNCTIONS
chris@162 48 */
chris@162 49
chris@162 50 void printHook(double timestampSecs, const char *printLabel, const char *msgString, void *userData) {
chris@162 51 printf("Message from Heavy patch: [@ %.3f] %s: %s\n", timestampSecs, printLabel, msgString);
chris@162 52 }
chris@162 53
chris@162 54 static void sendHook(
chris@162 55 double timestamp, // in milliseconds
chris@162 56 const char *receiverName,
chris@162 57 const HvMessage *const m,
chris@162 58 void *userData) {
chris@162 59
chris@162 60 // only react to messages sent to receivers named "hello"
chris@162 61 if (!strncmp(receiverName, "hello", 5)) {
chris@162 62 }
chris@162 63
chris@162 64 }
chris@162 65
chris@162 66 /*
chris@162 67 * RENDER INITIALISATION, LOOP & CLEANUP
chris@162 68 */
chris@162 69
chris@162 70
chris@162 71 // bool initialise_render(int numMatrixChannels, int numAudioChannels,
chris@162 72 // int numMatrixFramesPerPeriod,
chris@162 73 // int numAudioFramesPerPeriod,
chris@162 74 // float matrixSampleRate, float audioSampleRate,
chris@162 75 // void *userData)
chris@162 76 // {
chris@162 77 bool setup(BeagleRTContext *context, void *userData) {
chris@162 78
chris@162 79 /* HEAVY */
chris@162 80
chris@162 81 gHeavyContext = hv_bbb_new(context->audioSampleRate);
chris@162 82
chris@162 83 gHvInputChannels = hv_getNumInputChannels(gHeavyContext);
chris@162 84 gHvOutputChannels = hv_getNumOutputChannels(gHeavyContext);
chris@162 85
chris@162 86 // srand ( time(NULL) );
chris@162 87
chris@162 88 rt_printf("Starting Heavy context with %d input channels and %d output channels\n",
chris@162 89 gHvInputChannels, gHvOutputChannels);
chris@162 90
chris@162 91 if(gHvInputChannels != 0) {
chris@162 92 gHvInputBuffers = (float *)calloc(gHvInputChannels * context->audioFrames,sizeof(float));
chris@162 93 //memset(gHvInputBuffers,0,gHvInputChannels * numAudioFramesPerPeriod * sizeof(float));
chris@162 94 }
chris@162 95 if(gHvOutputChannels != 0) {
chris@162 96 gHvOutputBuffers = (float *)calloc(gHvOutputChannels * context->audioFrames,sizeof(float));
chris@162 97 }
chris@162 98
chris@162 99 gInverseSampleRate = 1.0 / context->audioSampleRate;
chris@162 100
chris@162 101 // Set heavy print hook
chris@162 102 hv_setPrintHook(gHeavyContext, &printHook);
chris@162 103 // Set heavy send hook
chris@162 104 hv_setSendHook(gHeavyContext, sendHook);
chris@162 105
chris@162 106 return true;
chris@162 107 }
chris@162 108
chris@162 109
chris@162 110 // void render(int numMatrixFrames, int numAudioFrames, float *audioIn, float *audioOut,
chris@162 111 // uint16_t *matrixIn, uint16_t *matrixOut)
chris@162 112 // {
chris@162 113 void render(BeagleRTContext *context, void *userData)
chris@162 114 {
chris@162 115 // use this for thread management
chris@162 116 // if(gCount == 0) {
chris@162 117 // } else {
chris@162 118 // }
chris@162 119 // gCount++;
chris@162 120
chris@162 121 // De-interleave the data
chris@162 122 if(gHvInputBuffers != NULL) {
chris@162 123 for(int n = 0; n < context->audioFrames; n++) {
chris@162 124 for(int ch = 0; ch < gHvInputChannels; ch++) {
chris@162 125 if(ch >= context->audioChannels+context->analogChannels) {
chris@162 126 // THESE ARE PARAMETER INPUT 'CHANNELS' USED FOR ROUTING
chris@162 127 // 'sensor' outputs from routing channels of dac~ are passed through here
chris@162 128 break;
chris@162 129 } else {
chris@162 130 // If more than 2 ADC inputs are used in the pd patch, route the analog inputs
chris@162 131 // i.e. ADC3->analogIn0 etc. (first two are always audio inputs)
chris@162 132 if(ch >= context->audioChannels) {
chris@162 133 int m = n/2;
chris@162 134 float mIn = context->analogIn[m*context->analogChannels + (ch-context->audioChannels)];
chris@162 135 gHvInputBuffers[ch * context->audioFrames + n] = mIn;
chris@162 136 } else {
chris@162 137 gHvInputBuffers[ch * context->audioFrames + n] = context->audioIn[n * context->audioChannels + ch];
chris@162 138 }
chris@162 139 }
chris@162 140 }
chris@162 141 }
chris@162 142 }
chris@162 143
chris@162 144 // replacement for bang~ object
chris@162 145 //hv_vscheduleMessageForReceiver(gHeavyContext, "bbb_bang", 0.0f, "b");
chris@162 146
chris@162 147 hv_bbb_process_inline(gHeavyContext, gHvInputBuffers, gHvOutputBuffers, context->audioFrames);
chris@162 148
chris@162 149 // Interleave the output data
chris@162 150 if(gHvOutputBuffers != NULL) {
chris@162 151 for(int n = 0; n < context->audioFrames; n++) {
chris@162 152
chris@162 153 for(int ch = 0; ch < gHvOutputChannels; ch++) {
chris@162 154 if(ch >= context->audioChannels+context->analogChannels) {
chris@162 155 // THESE ARE SENSOR OUTPUT 'CHANNELS' USED FOR ROUTING
chris@162 156 // they are the content of the 'sensor output' dac~ channels
chris@162 157 } else {
chris@162 158 if(ch >= context->audioChannels) {
chris@162 159 int m = n/2;
chris@162 160 // float mOut = (float)gHvOutputBuffers[ch*numAudioFrames + n];
chris@162 161 // mOut = constrain(mOut,0.0,1.0);
chris@162 162 context->analogOut[m * context->analogFrames + (ch-context->audioChannels)] = constrain(gHvOutputBuffers[ch*context->audioFrames + n],0.0,1.0);
chris@162 163 } else {
chris@162 164 context->audioOut[n * context->audioChannels + ch] = gHvOutputBuffers[ch * context->audioFrames + n];
chris@162 165 }
chris@162 166 }
chris@162 167 }
chris@162 168 }
chris@162 169 }
chris@162 170
chris@162 171 }
chris@162 172
chris@162 173
chris@162 174 void cleanup(BeagleRTContext *context, void *userData)
chris@162 175 {
chris@162 176
chris@162 177 hv_bbb_free(gHeavyContext);
chris@162 178 if(gHvInputBuffers != NULL)
chris@162 179 free(gHvInputBuffers);
chris@162 180 if(gHvOutputBuffers != NULL)
chris@162 181 free(gHvOutputBuffers);
chris@162 182
chris@162 183 }