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