comparison projects/heavy/circularBuffer/render.cpp @ 163:20b52283c7b4 heavy-updated

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