Mercurial > hg > beaglert
diff scripts/hvresources/render.cpp @ 160:5bcf04234f80 heavy-updated
- added -std=c99 to Makefile for user-supplied C files (required for heavy files)
- changed heavy core render.cpp file to use latest API and removed all redundant functions (e.g. foleyDesigner/touchkey stuff)
- use build_pd.sh to compile and run pd files (-h for usage instructions)
author | chnrx <chris.heinrichs@gmail.com> |
---|---|
date | Thu, 05 Nov 2015 18:58:26 +0000 |
parents | |
children | e6558ce09884 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/hvresources/render.cpp Thu Nov 05 18:58:26 2015 +0000 @@ -0,0 +1,183 @@ +/* + * render.cpp + * + * Template render.cpp file for on-board heavy compiling + * + * N.B. this is currently *not* compatible with foleyDesigner source files! + * + * Created on: November 5, 2015 + * + * Christian Heinrichs + * + */ + +#include <BeagleRT.h> +#include <cmath> +#include "../include/Utilities.h" +#include "Heavy_bbb.h" + +// #include "I2c_TouchKey.h" + +// #include "../include/UdpServer.h" +// #include "../include/UdpClient.h" +// #include <iostream> +// #include <fstream> +// #include "../include/ReceiveAudioThread.h" + +// #include "../include/render.h" +// #include <arm_neon.h> +// #include <time.h> +// #include <sndfile.h> + +// #include "../include/RTAudio.h" +// #include <rtdk.h> + + +/* + * HEAVY CONTEXT & BUFFERS + */ + +Hv_bbb *gHeavyContext; +float *gHvInputBuffers = NULL, *gHvOutputBuffers = NULL; +int gHvInputChannels = 0, gHvOutputChannels = 0; + +float gInverseSampleRate; + +/* + * HEAVY FUNCTIONS + */ + +void printHook(double timestampSecs, const char *printLabel, const char *msgString, void *userData) { + printf("Message from Heavy patch: [@ %.3f] %s: %s\n", timestampSecs, printLabel, msgString); +} + +static void sendHook( + double timestamp, // in milliseconds + const char *receiverName, + const HvMessage *const m, + void *userData) { + + // only react to messages sent to receivers named "hello" + if (!strncmp(receiverName, "hello", 5)) { + } + +} + +/* + * RENDER INITIALISATION, LOOP & CLEANUP + */ + + +// bool initialise_render(int numMatrixChannels, int numAudioChannels, +// int numMatrixFramesPerPeriod, +// int numAudioFramesPerPeriod, +// float matrixSampleRate, float audioSampleRate, +// void *userData) +// { +bool setup(BeagleRTContext *context, void *userData) { + + /* HEAVY */ + + gHeavyContext = hv_bbb_new(context->audioSampleRate); + + gHvInputChannels = hv_getNumInputChannels(gHeavyContext); + gHvOutputChannels = hv_getNumOutputChannels(gHeavyContext); + + // srand ( time(NULL) ); + + rt_printf("Starting Heavy context with %d input channels and %d output channels\n", + gHvInputChannels, gHvOutputChannels); + + if(gHvInputChannels != 0) { + gHvInputBuffers = (float *)calloc(gHvInputChannels * context->audioFrames,sizeof(float)); + //memset(gHvInputBuffers,0,gHvInputChannels * numAudioFramesPerPeriod * sizeof(float)); + } + if(gHvOutputChannels != 0) { + gHvOutputBuffers = (float *)calloc(gHvOutputChannels * context->audioFrames,sizeof(float)); + } + + gInverseSampleRate = 1.0 / context->audioSampleRate; + + // Set heavy print hook + hv_setPrintHook(gHeavyContext, &printHook); + // Set heavy send hook + hv_setSendHook(gHeavyContext, sendHook); + + return true; +} + + +// void render(int numMatrixFrames, int numAudioFrames, float *audioIn, float *audioOut, +// uint16_t *matrixIn, uint16_t *matrixOut) +// { +void render(BeagleRTContext *context, void *userData) +{ + // use this for thread management + // if(gCount == 0) { + // } else { + // } + // gCount++; + + // De-interleave the data + if(gHvInputBuffers != NULL) { + for(int n = 0; n < context->audioFrames; n++) { + for(int ch = 0; ch < gHvInputChannels; ch++) { + if(ch >= context->audioChannels+context->analogChannels) { + // THESE ARE PARAMETER INPUT 'CHANNELS' USED FOR ROUTING + // 'sensor' outputs from routing channels of dac~ are passed through here + break; + } else { + // If more than 2 ADC inputs are used in the pd patch, route the analog inputs + // i.e. ADC3->analogIn0 etc. (first two are always audio inputs) + if(ch >= context->audioChannels) { + int m = n/2; + float mIn = context->analogIn[m*context->analogChannels + (ch-context->audioChannels)]; + gHvInputBuffers[ch * context->audioFrames + n] = mIn; + } else { + gHvInputBuffers[ch * context->audioFrames + n] = context->audioIn[n * context->audioChannels + ch]; + } + } + } + } + } + + // replacement for bang~ object + //hv_vscheduleMessageForReceiver(gHeavyContext, "bbb_bang", 0.0f, "b"); + + hv_bbb_process_inline(gHeavyContext, gHvInputBuffers, gHvOutputBuffers, context->audioFrames); + + // Interleave the output data + if(gHvOutputBuffers != NULL) { + for(int n = 0; n < context->audioFrames; n++) { + + for(int ch = 0; ch < gHvOutputChannels; ch++) { + if(ch >= context->audioChannels+context->analogChannels) { + // THESE ARE SENSOR OUTPUT 'CHANNELS' USED FOR ROUTING + // they are the content of the 'sensor output' dac~ channels + } else { + if(ch >= context->audioChannels) { + int m = n/2; + // float mOut = (float)gHvOutputBuffers[ch*numAudioFrames + n]; + // mOut = constrain(mOut,0.0,1.0); + context->analogOut[m * context->analogFrames + (ch-context->audioChannels)] = constrain(gHvOutputBuffers[ch*context->audioFrames + n],0.0,1.0); + } else { + context->audioOut[n * context->audioChannels + ch] = gHvOutputBuffers[ch * context->audioFrames + n]; + } + } + } + } + } + +} + + +void cleanup(BeagleRTContext *context, void *userData) +{ + + hv_bbb_free(gHeavyContext); + if(gHvInputBuffers != NULL) + free(gHvInputBuffers); + if(gHvOutputBuffers != NULL) + free(gHvOutputBuffers); + +}