annotate scripts/hvresources/render.cpp @ 269:ac8eb07afcf5

Oxygen text added to each render.cpp file for the default projects. Text includes project explanation from Wiki, edited in places. Empty project added as a default project. Doxyfile updated. Each of the project locations added to INPUT configuration option. Consider just watching the whole project file so all new projects are automatically pulled through.
author Robert Jack <robert.h.jack@gmail.com>
date Tue, 17 May 2016 15:40:16 +0100
parents c768ed1055b0
children 156e6955ccf6
rev   line source
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>
giuliomoro@198 15 #include <Midi.h>
chris@160 16 #include <cmath>
chris@160 17 #include "../include/Utilities.h"
chris@160 18 #include "Heavy_bbb.h"
chris@190 19 #include <string.h>
chris@190 20 #include <stdlib.h>
chris@190 21 #include <string.h>
chris@160 22 /*
chris@160 23 * HEAVY CONTEXT & BUFFERS
chris@160 24 */
chris@160 25
chris@160 26 Hv_bbb *gHeavyContext;
chris@160 27 float *gHvInputBuffers = NULL, *gHvOutputBuffers = NULL;
chris@160 28 int gHvInputChannels = 0, gHvOutputChannels = 0;
chris@160 29
chris@160 30 float gInverseSampleRate;
chris@160 31
chris@160 32 /*
chris@160 33 * HEAVY FUNCTIONS
chris@160 34 */
chris@160 35
chris@160 36 void printHook(double timestampSecs, const char *printLabel, const char *msgString, void *userData) {
chris@160 37 printf("Message from Heavy patch: [@ %.3f] %s: %s\n", timestampSecs, printLabel, msgString);
chris@160 38 }
chris@160 39
chris@160 40 static void sendHook(
chris@160 41 double timestamp, // in milliseconds
chris@160 42 const char *receiverName,
chris@160 43 const HvMessage *const m,
chris@160 44 void *userData) {
chris@160 45
chris@160 46 // only react to messages sent to receivers named "hello"
chris@160 47 if (!strncmp(receiverName, "hello", 5)) {
chris@160 48 }
chris@160 49
chris@160 50 }
chris@160 51
chris@160 52 /*
chris@166 53 * SETUP, RENDER LOOP & CLEANUP
chris@160 54 */
chris@160 55
giuliomoro@198 56 Midi midi;
chris@160 57 bool setup(BeagleRTContext *context, void *userData) {
chris@160 58
chris@160 59 /* HEAVY */
chris@160 60
chris@160 61 gHeavyContext = hv_bbb_new(context->audioSampleRate);
chris@160 62
chris@160 63 gHvInputChannels = hv_getNumInputChannels(gHeavyContext);
chris@160 64 gHvOutputChannels = hv_getNumOutputChannels(gHeavyContext);
chris@160 65
chris@160 66 rt_printf("Starting Heavy context with %d input channels and %d output channels\n",
chris@160 67 gHvInputChannels, gHvOutputChannels);
chris@160 68
chris@160 69 if(gHvInputChannels != 0) {
chris@160 70 gHvInputBuffers = (float *)calloc(gHvInputChannels * context->audioFrames,sizeof(float));
chris@160 71 }
chris@160 72 if(gHvOutputChannels != 0) {
chris@160 73 gHvOutputBuffers = (float *)calloc(gHvOutputChannels * context->audioFrames,sizeof(float));
chris@160 74 }
chris@160 75
chris@160 76 gInverseSampleRate = 1.0 / context->audioSampleRate;
chris@160 77
chris@160 78 // Set heavy print hook
chris@160 79 hv_setPrintHook(gHeavyContext, &printHook);
chris@160 80 // Set heavy send hook
chris@160 81 hv_setSendHook(gHeavyContext, sendHook);
chris@160 82
giuliomoro@198 83 midi.readFrom(0);
giuliomoro@198 84 midi.writeTo(0);
giuliomoro@198 85 midi.enableParser(true);
chris@160 86 return true;
chris@160 87 }
chris@160 88
chris@160 89
chris@160 90 void render(BeagleRTContext *context, void *userData)
chris@160 91 {
chris@160 92
chris@160 93 // De-interleave the data
chris@160 94 if(gHvInputBuffers != NULL) {
chris@160 95 for(int n = 0; n < context->audioFrames; n++) {
chris@160 96 for(int ch = 0; ch < gHvInputChannels; ch++) {
chris@160 97 if(ch >= context->audioChannels+context->analogChannels) {
chris@160 98 // THESE ARE PARAMETER INPUT 'CHANNELS' USED FOR ROUTING
chris@160 99 // 'sensor' outputs from routing channels of dac~ are passed through here
chris@160 100 break;
chris@160 101 } else {
chris@160 102 // If more than 2 ADC inputs are used in the pd patch, route the analog inputs
chris@160 103 // i.e. ADC3->analogIn0 etc. (first two are always audio inputs)
chris@160 104 if(ch >= context->audioChannels) {
chris@160 105 int m = n/2;
chris@160 106 float mIn = context->analogIn[m*context->analogChannels + (ch-context->audioChannels)];
chris@160 107 gHvInputBuffers[ch * context->audioFrames + n] = mIn;
chris@160 108 } else {
chris@160 109 gHvInputBuffers[ch * context->audioFrames + n] = context->audioIn[n * context->audioChannels + ch];
chris@160 110 }
chris@160 111 }
chris@160 112 }
chris@160 113 }
chris@160 114 }
chris@160 115
chris@160 116 // replacement for bang~ object
chris@160 117 //hv_vscheduleMessageForReceiver(gHeavyContext, "bbb_bang", 0.0f, "b");
giuliomoro@198 118 {
giuliomoro@198 119 int num;
giuliomoro@198 120 while((num = midi.getParser()->numAvailableMessages()) > 0){
giuliomoro@198 121 static MidiChannelMessage message;
giuliomoro@198 122 message = midi.getParser()->getNextChannelMessage();
giuliomoro@198 123 switch(message.getType()){
giuliomoro@198 124 case kmmNoteOn: {
giuliomoro@198 125 // message.prettyPrint();
giuliomoro@198 126 float noteNumber = message.getDataByte(0);
giuliomoro@198 127 float velocity = message.getDataByte(1);
giuliomoro@198 128 float channel = message.getChannel();
giuliomoro@198 129 // rt_printf("message: noteNumber: %f, velocity: %f, channel: %f\n", noteNumber, velocity, channel);
giuliomoro@229 130 hv_vscheduleMessageForReceiver(gHeavyContext, "bela_notein", 0, "fff", noteNumber, velocity, channel);
giuliomoro@198 131 }
giuliomoro@198 132 break;
giuliomoro@198 133 case kmmControlChange: {
giuliomoro@229 134 hv_vscheduleMessageForReceiver(gHeavyContext, "bela_ctlin", 0, "fff",
giuliomoro@198 135 (float)message.getDataByte(1), (float)message.getDataByte(0), (float)message.getChannel());
giuliomoro@198 136 }
giuliomoro@198 137 break;
giuliomoro@198 138 case kmmProgramChange:
giuliomoro@229 139 hv_vscheduleMessageForReceiver(gHeavyContext, "bela_pgmin", 0, "ff",
giuliomoro@198 140 (float)message.getDataByte(0), (float)message.getChannel());
giuliomoro@198 141 break;
giuliomoro@198 142 }
giuliomoro@198 143 }
giuliomoro@198 144 }
giuliomoro@198 145 // hv_sendFloatToReceiver(gHeavyContext, "notein", 1.123f);
giuliomoro@198 146
chris@160 147
chris@160 148 hv_bbb_process_inline(gHeavyContext, gHvInputBuffers, gHvOutputBuffers, context->audioFrames);
chris@160 149
chris@160 150 // Interleave the output data
chris@160 151 if(gHvOutputBuffers != NULL) {
chris@160 152 for(int n = 0; n < context->audioFrames; n++) {
chris@160 153
chris@160 154 for(int ch = 0; ch < gHvOutputChannels; ch++) {
chris@160 155 if(ch >= context->audioChannels+context->analogChannels) {
chris@160 156 // THESE ARE SENSOR OUTPUT 'CHANNELS' USED FOR ROUTING
chris@160 157 // they are the content of the 'sensor output' dac~ channels
chris@160 158 } else {
chris@160 159 if(ch >= context->audioChannels) {
chris@160 160 int m = n/2;
chris@160 161 context->analogOut[m * context->analogFrames + (ch-context->audioChannels)] = constrain(gHvOutputBuffers[ch*context->audioFrames + n],0.0,1.0);
chris@160 162 } else {
chris@160 163 context->audioOut[n * context->audioChannels + ch] = gHvOutputBuffers[ch * context->audioFrames + n];
chris@160 164 }
chris@160 165 }
chris@160 166 }
chris@160 167 }
chris@160 168 }
chris@160 169
chris@160 170 }
chris@160 171
chris@160 172
chris@160 173 void cleanup(BeagleRTContext *context, void *userData)
chris@160 174 {
chris@160 175
chris@160 176 hv_bbb_free(gHeavyContext);
chris@160 177 if(gHvInputBuffers != NULL)
chris@160 178 free(gHvInputBuffers);
chris@160 179 if(gHvOutputBuffers != NULL)
chris@160 180 free(gHvOutputBuffers);
chris@160 181
chris@160 182 }