chris@163: /* chris@163: * render.cpp chris@163: * chris@163: * Template render.cpp file for on-board heavy compiling chris@163: * chris@163: * N.B. this is currently *not* compatible with foleyDesigner source files! chris@163: * chris@163: * Created on: November 5, 2015 chris@163: * chris@163: * Christian Heinrichs chris@163: * chris@163: */ chris@163: chris@163: #include chris@163: #include chris@163: #include "../include/Utilities.h" chris@163: #include "Heavy_bbb.h" chris@163: chris@163: // #include "I2c_TouchKey.h" chris@163: chris@163: // #include "../include/UdpServer.h" chris@163: // #include "../include/UdpClient.h" chris@163: // #include chris@163: // #include chris@163: // #include "../include/ReceiveAudioThread.h" chris@163: chris@163: // #include "../include/render.h" chris@163: // #include chris@163: // #include chris@163: // #include chris@163: chris@163: // #include "../include/RTAudio.h" chris@163: // #include chris@163: chris@163: chris@163: /* chris@163: * HEAVY CONTEXT & BUFFERS chris@163: */ chris@163: chris@163: Hv_bbb *gHeavyContext; chris@163: float *gHvInputBuffers = NULL, *gHvOutputBuffers = NULL; chris@163: int gHvInputChannels = 0, gHvOutputChannels = 0; chris@163: chris@163: float gInverseSampleRate; chris@163: chris@163: /* chris@163: * HEAVY FUNCTIONS chris@163: */ chris@163: chris@163: void printHook(double timestampSecs, const char *printLabel, const char *msgString, void *userData) { chris@163: printf("Message from Heavy patch: [@ %.3f] %s: %s\n", timestampSecs, printLabel, msgString); chris@163: } chris@163: chris@163: static void sendHook( chris@163: double timestamp, // in milliseconds chris@163: const char *receiverName, chris@163: const HvMessage *const m, chris@163: void *userData) { chris@163: chris@163: // only react to messages sent to receivers named "hello" chris@163: if (!strncmp(receiverName, "hello", 5)) { chris@163: } chris@163: chris@163: } chris@163: chris@163: /* chris@163: * RENDER INITIALISATION, LOOP & CLEANUP chris@163: */ chris@163: chris@163: chris@163: // bool initialise_render(int numMatrixChannels, int numAudioChannels, chris@163: // int numMatrixFramesPerPeriod, chris@163: // int numAudioFramesPerPeriod, chris@163: // float matrixSampleRate, float audioSampleRate, chris@163: // void *userData) chris@163: // { chris@163: bool setup(BeagleRTContext *context, void *userData) { chris@163: chris@163: /* HEAVY */ chris@163: chris@163: gHeavyContext = hv_bbb_new(context->audioSampleRate); chris@163: chris@163: gHvInputChannels = hv_getNumInputChannels(gHeavyContext); chris@163: gHvOutputChannels = hv_getNumOutputChannels(gHeavyContext); chris@163: chris@163: // srand ( time(NULL) ); chris@163: chris@163: rt_printf("Starting Heavy context with %d input channels and %d output channels\n", chris@163: gHvInputChannels, gHvOutputChannels); chris@163: chris@163: if(gHvInputChannels != 0) { chris@163: gHvInputBuffers = (float *)calloc(gHvInputChannels * context->audioFrames,sizeof(float)); chris@163: //memset(gHvInputBuffers,0,gHvInputChannels * numAudioFramesPerPeriod * sizeof(float)); chris@163: } chris@163: if(gHvOutputChannels != 0) { chris@163: gHvOutputBuffers = (float *)calloc(gHvOutputChannels * context->audioFrames,sizeof(float)); chris@163: } chris@163: chris@163: gInverseSampleRate = 1.0 / context->audioSampleRate; chris@163: chris@163: // Set heavy print hook chris@163: hv_setPrintHook(gHeavyContext, &printHook); chris@163: // Set heavy send hook chris@163: hv_setSendHook(gHeavyContext, sendHook); chris@163: chris@163: return true; chris@163: } chris@163: chris@163: chris@163: // void render(int numMatrixFrames, int numAudioFrames, float *audioIn, float *audioOut, chris@163: // uint16_t *matrixIn, uint16_t *matrixOut) chris@163: // { chris@163: void render(BeagleRTContext *context, void *userData) chris@163: { chris@163: // use this for thread management chris@163: // if(gCount == 0) { chris@163: // } else { chris@163: // } chris@163: // gCount++; chris@163: chris@163: // De-interleave the data chris@163: if(gHvInputBuffers != NULL) { chris@163: for(int n = 0; n < context->audioFrames; n++) { chris@163: for(int ch = 0; ch < gHvInputChannels; ch++) { chris@163: if(ch >= context->audioChannels+context->analogChannels) { chris@163: // THESE ARE PARAMETER INPUT 'CHANNELS' USED FOR ROUTING chris@163: // 'sensor' outputs from routing channels of dac~ are passed through here chris@163: break; chris@163: } else { chris@163: // If more than 2 ADC inputs are used in the pd patch, route the analog inputs chris@163: // i.e. ADC3->analogIn0 etc. (first two are always audio inputs) chris@163: if(ch >= context->audioChannels) { chris@163: int m = n/2; chris@163: float mIn = context->analogIn[m*context->analogChannels + (ch-context->audioChannels)]; chris@163: gHvInputBuffers[ch * context->audioFrames + n] = mIn; chris@163: } else { chris@163: gHvInputBuffers[ch * context->audioFrames + n] = context->audioIn[n * context->audioChannels + ch]; chris@163: } chris@163: } chris@163: } chris@163: } chris@163: } chris@163: chris@163: // replacement for bang~ object chris@163: //hv_vscheduleMessageForReceiver(gHeavyContext, "bbb_bang", 0.0f, "b"); chris@163: chris@163: hv_bbb_process_inline(gHeavyContext, gHvInputBuffers, gHvOutputBuffers, context->audioFrames); chris@163: chris@163: // Interleave the output data chris@163: if(gHvOutputBuffers != NULL) { chris@163: for(int n = 0; n < context->audioFrames; n++) { chris@163: chris@163: for(int ch = 0; ch < gHvOutputChannels; ch++) { chris@163: if(ch >= context->audioChannels+context->analogChannels) { chris@163: // THESE ARE SENSOR OUTPUT 'CHANNELS' USED FOR ROUTING chris@163: // they are the content of the 'sensor output' dac~ channels chris@163: } else { chris@163: if(ch >= context->audioChannels) { chris@163: int m = n/2; chris@163: // float mOut = (float)gHvOutputBuffers[ch*numAudioFrames + n]; chris@163: // mOut = constrain(mOut,0.0,1.0); chris@163: context->analogOut[m * context->analogFrames + (ch-context->audioChannels)] = constrain(gHvOutputBuffers[ch*context->audioFrames + n],0.0,1.0); chris@163: } else { chris@163: context->audioOut[n * context->audioChannels + ch] = gHvOutputBuffers[ch * context->audioFrames + n]; chris@163: } chris@163: } chris@163: } chris@163: } chris@163: } chris@163: chris@163: } chris@163: chris@163: chris@163: void cleanup(BeagleRTContext *context, void *userData) chris@163: { chris@163: chris@163: hv_bbb_free(gHeavyContext); chris@163: if(gHvInputBuffers != NULL) chris@163: free(gHvInputBuffers); chris@163: if(gHvOutputBuffers != NULL) chris@163: free(gHvOutputBuffers); chris@163: chris@163: }