comparison scripts/hvresources/heavy_render.cpp @ 442:6462d0cc8906 prerelease

build_pd_heavy.sh: major refactoring. Safer, nicer, cleaner
author Giulio Moro <giuliomoro@yahoo.it>
date Sun, 19 Jun 2016 00:35:41 +0100
parents scripts/hvresources/render.cpp@9dc5a0ccad25
children 4ff80956c27a
comparison
equal deleted inserted replaced
441:b596c72f0382 442:6462d0cc8906
1 /*
2 * render.cpp
3 *
4 * Template render.cpp file for on-board heavy compiling
5 *
6 * N.B. this is currently *not* compatible with foleyDesigner source files!
7 *
8 * Created on: November 5, 2015
9 *
10 * Christian Heinrichs
11 *
12 */
13
14 #include <Bela.h>
15 #include <Midi.h>
16 #include <cmath>
17 #include "Heavy_bbb.h"
18 #include <string.h>
19 #include <stdlib.h>
20 #include <string.h>
21 /*
22 * HEAVY CONTEXT & BUFFERS
23 */
24
25 Hv_bbb *gHeavyContext;
26 float *gHvInputBuffers = NULL, *gHvOutputBuffers = NULL;
27 int gHvInputChannels = 0, gHvOutputChannels = 0;
28
29 float gInverseSampleRate;
30
31 /*
32 * HEAVY FUNCTIONS
33 */
34
35 void printHook(double timestampSecs, const char *printLabel, const char *msgString, void *userData) {
36 printf("Message from Heavy patch: [@ %.3f] %s: %s\n", timestampSecs, printLabel, msgString);
37 }
38
39 static void sendHook(
40 double timestamp, // in milliseconds
41 const char *receiverName,
42 const HvMessage *const m,
43 void *userData) {
44
45 // only react to messages sent to receivers named "hello"
46 if (!strncmp(receiverName, "hello", 5)) {
47 }
48
49 }
50
51 /*
52 * SETUP, RENDER LOOP & CLEANUP
53 */
54
55 Midi midi;
56 bool setup(BelaContext *context, void *userData) {
57
58 /* HEAVY */
59
60 gHeavyContext = hv_bbb_new(context->audioSampleRate);
61
62 gHvInputChannels = hv_getNumInputChannels(gHeavyContext);
63 gHvOutputChannels = hv_getNumOutputChannels(gHeavyContext);
64
65 rt_printf("Starting Heavy context with %d input channels and %d output channels\n",
66 gHvInputChannels, gHvOutputChannels);
67
68 if(gHvInputChannels != 0) {
69 gHvInputBuffers = (float *)calloc(gHvInputChannels * context->audioFrames,sizeof(float));
70 }
71 if(gHvOutputChannels != 0) {
72 gHvOutputBuffers = (float *)calloc(gHvOutputChannels * context->audioFrames,sizeof(float));
73 }
74
75 gInverseSampleRate = 1.0 / context->audioSampleRate;
76
77 // Set heavy print hook
78 hv_setPrintHook(gHeavyContext, &printHook);
79 // Set heavy send hook
80 hv_setSendHook(gHeavyContext, sendHook);
81
82 midi.readFrom(0);
83 midi.writeTo(0);
84 midi.enableParser(true);
85 return true;
86 }
87
88
89 void render(BelaContext *context, void *userData)
90 {
91
92 // De-interleave the data
93 if(gHvInputBuffers != NULL) {
94 for(int n = 0; n < context->audioFrames; n++) {
95 for(int ch = 0; ch < gHvInputChannels; ch++) {
96 if(ch >= context->audioChannels+context->analogChannels) {
97 // THESE ARE PARAMETER INPUT 'CHANNELS' USED FOR ROUTING
98 // 'sensor' outputs from routing channels of dac~ are passed through here
99 break;
100 } else {
101 // If more than 2 ADC inputs are used in the pd patch, route the analog inputs
102 // i.e. ADC3->analogIn0 etc. (first two are always audio inputs)
103 if(ch >= context->audioChannels) {
104 int m = n/2;
105 float mIn = context->analogIn[m*context->analogChannels + (ch-context->audioChannels)];
106 gHvInputBuffers[ch * context->audioFrames + n] = mIn;
107 } else {
108 gHvInputBuffers[ch * context->audioFrames + n] = context->audioIn[n * context->audioChannels + ch];
109 }
110 }
111 }
112 }
113 }
114
115 // replacement for bang~ object
116 //hv_vscheduleMessageForReceiver(gHeavyContext, "bbb_bang", 0.0f, "b");
117 {
118 int num;
119 unsigned int hvHashes[3];
120 hvHashes[0] = hv_stringToHash("bela_notein");
121 hvHashes[1] = hv_stringToHash("bela_ctlin");
122 hvHashes[2] = hv_stringToHash("bela_pgmin");
123 while((num = midi.getParser()->numAvailableMessages()) > 0){
124 static MidiChannelMessage message;
125 message = midi.getParser()->getNextChannelMessage();
126 switch(message.getType()){
127 case kmmNoteOn: {
128 // message.prettyPrint();
129 float noteNumber = message.getDataByte(0);
130 float velocity = message.getDataByte(1);
131 float channel = message.getChannel();
132 // rt_printf("message: noteNumber: %f, velocity: %f, channel: %f\n", noteNumber, velocity, channel);
133 hv_vscheduleMessageForReceiver(gHeavyContext, hvHashes[0], 0, "fff", noteNumber, velocity, channel);
134 }
135 break;
136 case kmmControlChange: {
137 hv_vscheduleMessageForReceiver(gHeavyContext, hvHashes[1], 0, "fff",
138 (float)message.getDataByte(1), (float)message.getDataByte(0), (float)message.getChannel());
139 }
140 break;
141 case kmmProgramChange:
142 hv_vscheduleMessageForReceiver(gHeavyContext, hvHashes[2], 0, "ff",
143 (float)message.getDataByte(0), (float)message.getChannel());
144 break;
145 }
146 }
147 }
148 // hv_sendFloatToReceiver(gHeavyContext, "notein", 1.123f);
149
150
151 hv_bbb_process_inline(gHeavyContext, gHvInputBuffers, gHvOutputBuffers, context->audioFrames);
152
153 // Interleave the output data
154 if(gHvOutputBuffers != NULL) {
155 for(int n = 0; n < context->audioFrames; n++) {
156
157 for(int ch = 0; ch < gHvOutputChannels; ch++) {
158 if(ch >= context->audioChannels+context->analogChannels) {
159 // THESE ARE SENSOR OUTPUT 'CHANNELS' USED FOR ROUTING
160 // they are the content of the 'sensor output' dac~ channels
161 } else {
162 if(ch >= context->audioChannels) {
163 int m = n/2;
164 context->analogOut[m * context->analogFrames + (ch-context->audioChannels)] = constrain(gHvOutputBuffers[ch*context->audioFrames + n],0.0,1.0);
165 } else {
166 context->audioOut[n * context->audioChannels + ch] = gHvOutputBuffers[ch * context->audioFrames + n];
167 }
168 }
169 }
170 }
171 }
172
173 }
174
175
176 void cleanup(BelaContext *context, void *userData)
177 {
178
179 hv_bbb_free(gHeavyContext);
180 if(gHvInputBuffers != NULL)
181 free(gHvInputBuffers);
182 if(gHvOutputBuffers != NULL)
183 free(gHvOutputBuffers);
184
185 }