chris@160
|
1 /*
|
chris@160
|
2 * render.cpp
|
chris@160
|
3 *
|
chris@160
|
4 * Template render.cpp file for on-board heavy compiling
|
chris@160
|
5 *
|
chris@160
|
6 * N.B. this is currently *not* compatible with foleyDesigner source files!
|
chris@160
|
7 *
|
chris@160
|
8 * Created on: November 5, 2015
|
chris@160
|
9 *
|
chris@160
|
10 * Christian Heinrichs
|
chris@160
|
11 *
|
chris@160
|
12 */
|
chris@160
|
13
|
chris@160
|
14 #include <BeagleRT.h>
|
chris@160
|
15 #include <cmath>
|
chris@160
|
16 #include "../include/Utilities.h"
|
chris@160
|
17 #include "Heavy_bbb.h"
|
chris@160
|
18
|
chris@160
|
19 /*
|
chris@160
|
20 * HEAVY CONTEXT & BUFFERS
|
chris@160
|
21 */
|
chris@160
|
22
|
chris@160
|
23 Hv_bbb *gHeavyContext;
|
chris@160
|
24 float *gHvInputBuffers = NULL, *gHvOutputBuffers = NULL;
|
chris@160
|
25 int gHvInputChannels = 0, gHvOutputChannels = 0;
|
chris@160
|
26
|
chris@160
|
27 float gInverseSampleRate;
|
chris@160
|
28
|
chris@160
|
29 /*
|
chris@160
|
30 * HEAVY FUNCTIONS
|
chris@160
|
31 */
|
chris@160
|
32
|
chris@160
|
33 void printHook(double timestampSecs, const char *printLabel, const char *msgString, void *userData) {
|
chris@160
|
34 printf("Message from Heavy patch: [@ %.3f] %s: %s\n", timestampSecs, printLabel, msgString);
|
chris@160
|
35 }
|
chris@160
|
36
|
chris@160
|
37 static void sendHook(
|
chris@160
|
38 double timestamp, // in milliseconds
|
chris@160
|
39 const char *receiverName,
|
chris@160
|
40 const HvMessage *const m,
|
chris@160
|
41 void *userData) {
|
chris@160
|
42
|
chris@160
|
43 // only react to messages sent to receivers named "hello"
|
chris@160
|
44 if (!strncmp(receiverName, "hello", 5)) {
|
chris@160
|
45 }
|
chris@160
|
46
|
chris@160
|
47 }
|
chris@160
|
48
|
chris@160
|
49 /*
|
chris@166
|
50 * SETUP, RENDER LOOP & CLEANUP
|
chris@160
|
51 */
|
chris@160
|
52
|
chris@160
|
53 bool setup(BeagleRTContext *context, void *userData) {
|
chris@160
|
54
|
chris@160
|
55 /* HEAVY */
|
chris@160
|
56
|
chris@160
|
57 gHeavyContext = hv_bbb_new(context->audioSampleRate);
|
chris@160
|
58
|
chris@160
|
59 gHvInputChannels = hv_getNumInputChannels(gHeavyContext);
|
chris@160
|
60 gHvOutputChannels = hv_getNumOutputChannels(gHeavyContext);
|
chris@160
|
61
|
chris@160
|
62 rt_printf("Starting Heavy context with %d input channels and %d output channels\n",
|
chris@160
|
63 gHvInputChannels, gHvOutputChannels);
|
chris@160
|
64
|
chris@160
|
65 if(gHvInputChannels != 0) {
|
chris@160
|
66 gHvInputBuffers = (float *)calloc(gHvInputChannels * context->audioFrames,sizeof(float));
|
chris@160
|
67 }
|
chris@160
|
68 if(gHvOutputChannels != 0) {
|
chris@160
|
69 gHvOutputBuffers = (float *)calloc(gHvOutputChannels * context->audioFrames,sizeof(float));
|
chris@160
|
70 }
|
chris@160
|
71
|
chris@160
|
72 gInverseSampleRate = 1.0 / context->audioSampleRate;
|
chris@160
|
73
|
chris@160
|
74 // Set heavy print hook
|
chris@160
|
75 hv_setPrintHook(gHeavyContext, &printHook);
|
chris@160
|
76 // Set heavy send hook
|
chris@160
|
77 hv_setSendHook(gHeavyContext, sendHook);
|
chris@160
|
78
|
chris@160
|
79 return true;
|
chris@160
|
80 }
|
chris@160
|
81
|
chris@160
|
82
|
chris@160
|
83 void render(BeagleRTContext *context, void *userData)
|
chris@160
|
84 {
|
chris@160
|
85
|
chris@160
|
86 // De-interleave the data
|
chris@160
|
87 if(gHvInputBuffers != NULL) {
|
chris@160
|
88 for(int n = 0; n < context->audioFrames; n++) {
|
chris@160
|
89 for(int ch = 0; ch < gHvInputChannels; ch++) {
|
chris@160
|
90 if(ch >= context->audioChannels+context->analogChannels) {
|
chris@160
|
91 // THESE ARE PARAMETER INPUT 'CHANNELS' USED FOR ROUTING
|
chris@160
|
92 // 'sensor' outputs from routing channels of dac~ are passed through here
|
chris@160
|
93 break;
|
chris@160
|
94 } else {
|
chris@160
|
95 // If more than 2 ADC inputs are used in the pd patch, route the analog inputs
|
chris@160
|
96 // i.e. ADC3->analogIn0 etc. (first two are always audio inputs)
|
chris@160
|
97 if(ch >= context->audioChannels) {
|
chris@160
|
98 int m = n/2;
|
chris@160
|
99 float mIn = context->analogIn[m*context->analogChannels + (ch-context->audioChannels)];
|
chris@160
|
100 gHvInputBuffers[ch * context->audioFrames + n] = mIn;
|
chris@160
|
101 } else {
|
chris@160
|
102 gHvInputBuffers[ch * context->audioFrames + n] = context->audioIn[n * context->audioChannels + ch];
|
chris@160
|
103 }
|
chris@160
|
104 }
|
chris@160
|
105 }
|
chris@160
|
106 }
|
chris@160
|
107 }
|
chris@160
|
108
|
chris@160
|
109 // replacement for bang~ object
|
chris@160
|
110 //hv_vscheduleMessageForReceiver(gHeavyContext, "bbb_bang", 0.0f, "b");
|
chris@160
|
111
|
chris@160
|
112 hv_bbb_process_inline(gHeavyContext, gHvInputBuffers, gHvOutputBuffers, context->audioFrames);
|
chris@160
|
113
|
chris@160
|
114 // Interleave the output data
|
chris@160
|
115 if(gHvOutputBuffers != NULL) {
|
chris@160
|
116 for(int n = 0; n < context->audioFrames; n++) {
|
chris@160
|
117
|
chris@160
|
118 for(int ch = 0; ch < gHvOutputChannels; ch++) {
|
chris@160
|
119 if(ch >= context->audioChannels+context->analogChannels) {
|
chris@160
|
120 // THESE ARE SENSOR OUTPUT 'CHANNELS' USED FOR ROUTING
|
chris@160
|
121 // they are the content of the 'sensor output' dac~ channels
|
chris@160
|
122 } else {
|
chris@160
|
123 if(ch >= context->audioChannels) {
|
chris@160
|
124 int m = n/2;
|
chris@160
|
125 context->analogOut[m * context->analogFrames + (ch-context->audioChannels)] = constrain(gHvOutputBuffers[ch*context->audioFrames + n],0.0,1.0);
|
chris@160
|
126 } else {
|
chris@160
|
127 context->audioOut[n * context->audioChannels + ch] = gHvOutputBuffers[ch * context->audioFrames + n];
|
chris@160
|
128 }
|
chris@160
|
129 }
|
chris@160
|
130 }
|
chris@160
|
131 }
|
chris@160
|
132 }
|
chris@160
|
133
|
chris@160
|
134 }
|
chris@160
|
135
|
chris@160
|
136
|
chris@160
|
137 void cleanup(BeagleRTContext *context, void *userData)
|
chris@160
|
138 {
|
chris@160
|
139
|
chris@160
|
140 hv_bbb_free(gHeavyContext);
|
chris@160
|
141 if(gHvInputBuffers != NULL)
|
chris@160
|
142 free(gHvInputBuffers);
|
chris@160
|
143 if(gHvOutputBuffers != NULL)
|
chris@160
|
144 free(gHvOutputBuffers);
|
chris@160
|
145
|
chris@160
|
146 }
|