Mercurial > hg > beaglert
diff scripts/hvresources/heavy_render.cpp @ 482:4d5edf7ee953 prerelease
heavy: support for signal-rate digitals and Scope.
author | Giulio Moro <giuliomoro@yahoo.it> |
---|---|
date | Tue, 21 Jun 2016 14:27:26 +0100 |
parents | 4ff80956c27a |
children | 7f8d1a3e4cef |
line wrap: on
line diff
--- a/scripts/hvresources/heavy_render.cpp Tue Jun 21 14:26:33 2016 +0100 +++ b/scripts/hvresources/heavy_render.cpp Tue Jun 21 14:27:26 2016 +0100 @@ -13,8 +13,9 @@ #include <Bela.h> #include <Midi.h> +#include <Scope.h> #include <cmath> -#include "Heavy_bbb.h" +#include <Heavy_bbb.h> #include <string.h> #include <stdlib.h> #include <string.h> @@ -133,16 +134,27 @@ * SETUP, RENDER LOOP & CLEANUP */ +// 2 audio + (up to)8 analog + (up to) 16 digital + 4 scope outputs +static const unsigned int gChannelsInUse = 30; +static unsigned int gAnalogChannelsInUse = 8; // hard-coded for the moment, TODO: get it at run-time from hv_context +//static const unsigned int gFirstAudioChannel = 0; +static const unsigned int gFirstAnalogChannel = 2; +static const unsigned int gFirstDigitalChannel = 10; +static const unsigned int gFirstScopeChannel = 26; +static unsigned int gDigitalSigInChannelsInUse; +static unsigned int gDigitalSigOutChannelsInUse; - -// Midi +// Bela Midi Midi midi; unsigned int hvMidiHashes[7]; +// Bela Scope +Scope scope; +const unsigned int gMaxScopeChannels = 4; +unsigned int gScopeChannelsInUse; +float* gScopeOut; bool setup(BelaContext *context, void *userData) { - - printf("top o setup\n"); /* HEAVY */ hvMidiHashes[kmmNoteOn] = hv_stringToHash("__hv_notein"); hvMidiHashes[kmmNoteOff] = hv_stringToHash("noteoff"); // this is handled differently, see the render function @@ -152,15 +164,23 @@ hvMidiHashes[kmmChannelPressure] = hv_stringToHash("touchin"); hvMidiHashes[kmmPitchBend] = hv_stringToHash("bendin"); - printf("after midi o setup\n"); gHeavyContext = hv_bbb_new(context->audioSampleRate); - printf("aftet new o setup\n"); gHvInputChannels = hv_getNumInputChannels(gHeavyContext); gHvOutputChannels = hv_getNumOutputChannels(gHeavyContext); - rt_printf("Starting Heavy context with %d input channels and %d output channels\n", + gScopeChannelsInUse = gHvOutputChannels > gFirstScopeChannel ? + gHvOutputChannels - gFirstScopeChannel : 0; + gDigitalSigInChannelsInUse = gHvInputChannels > gFirstDigitalChannel ? + gHvInputChannels - gFirstDigitalChannel : 0; + gDigitalSigOutChannelsInUse = gHvOutputChannels > gFirstDigitalChannel ? + gHvOutputChannels - gFirstDigitalChannel - gScopeChannelsInUse: 0; + + printf("Starting Heavy context with %d input channels and %d output channels\n", gHvInputChannels, gHvOutputChannels); + printf("Channels in use:\n"); + printf("Digital in : %u, Digital out: %u\n", gDigitalSigInChannelsInUse, gDigitalSigOutChannelsInUse); + printf("Scope out: %u\n", gScopeChannelsInUse); if(gHvInputChannels != 0) { gHvInputBuffers = (float *)calloc(gHvInputChannels * context->audioFrames,sizeof(float)); @@ -168,7 +188,6 @@ if(gHvOutputChannels != 0) { gHvOutputBuffers = (float *)calloc(gHvOutputChannels * context->audioFrames,sizeof(float)); } - printf("mid o setup\n"); gInverseSampleRate = 1.0 / context->audioSampleRate; @@ -182,6 +201,11 @@ midi.writeTo(0); midi.enableParser(true); + if(gScopeChannelsInUse > 0){ + // block below copy/pasted from libpd, except + scope.setup(gScopeChannelsInUse, context->audioSampleRate); + gScopeOut = new float[gScopeChannelsInUse]; + } // Bela digital dcm.setCallback(sendDigitalMessage); if(context->digitalChannels > 0){ @@ -191,7 +215,6 @@ } // unlike libpd, no need here to bind the bela_digitalOut.. receivers - printf("end o setup\n"); return true; } @@ -303,13 +326,30 @@ // Bela digital in // note: in multiple places below we assume that the number of digital frames is same as number of audio - // digital in at message-rate + // Bela digital in at message-rate dcm.processInput(context->digital, context->digitalFrames); // Bela digital in at signal-rate - // TODO: not really straightforward to implement as Heavy determines the number of channels in use at compile time - // on the basis of the number of adc~ / dac~ of the patch ... Maybe we should always include - // a dummy [adc~ 27] [dac~ 27] to make sure all channels are always allocated and then leave them all unprocessed ? + if(gDigitalSigInChannelsInUse > 0) + { + unsigned int j, k; + float *p0, *p1; + const unsigned int gLibpdBlockSize = context->audioFrames; + const unsigned int audioFrameBase = 0; + float* gInBuf = gHvInputBuffers; + // block below copy/pasted from libpd, except + // 16 has been replaced with gDigitalSigInChannelsInUse + for (j = 0, p0 = gInBuf; j < gLibpdBlockSize; j++, p0++) { + unsigned int digitalFrame = audioFrameBase + j; + for (k = 0, p1 = p0 + gLibpdBlockSize * gFirstDigitalChannel; + k < gDigitalSigInChannelsInUse; ++k, p1 += gLibpdBlockSize) { + if(dcm.isSignalRate(k) && dcm.isInput(k)){ // only process input channels that are handled at signal rate + *p1 = digitalRead(context, digitalFrame, k); + } + } + } + } + // replacement for bang~ object //hv_vscheduleMessageForReceiver(gHeavyContext, "bbb_bang", 0.0f, "b"); @@ -317,11 +357,46 @@ hv_bbb_process_inline(gHeavyContext, gHvInputBuffers, gHvOutputBuffers, context->audioFrames); // Bela digital out - // digital out at signal-rate - // TODO: see note above. + // Bela digital out at signal-rate + if(gDigitalSigOutChannelsInUse > 0) + { + unsigned int j, k; + float *p0, *p1; + const unsigned int gLibpdBlockSize = context->audioFrames; + const unsigned int audioFrameBase = 0; + float* gOutBuf = gHvOutputBuffers; + // block below copy/pasted from libpd, except + // context->digitalChannels has been replaced with gDigitalSigOutChannelsInUse + for (j = 0, p0 = gOutBuf; j < gLibpdBlockSize; ++j, ++p0) { + unsigned int digitalFrame = (audioFrameBase + j); + for (k = 0, p1 = p0 + gLibpdBlockSize * gFirstDigitalChannel; + k < gDigitalSigOutChannelsInUse; k++, p1 += gLibpdBlockSize) { + if(dcm.isSignalRate(k) && dcm.isOutput(k)){ // only process output channels that are handled at signal rate + digitalWriteOnce(context, digitalFrame, k, *p1 > 0.5); + } + } + } + } + // Bela digital out at message-rate + dcm.processOutput(context->digital, context->digitalFrames); - // digital out at message-rate - dcm.processOutput(context->digital, context->digitalFrames); + // Bela scope + if(gScopeChannelsInUse > 0) + { + unsigned int j, k; + float *p0, *p1; + const unsigned int gLibpdBlockSize = context->audioFrames; + const unsigned int audioFrameBase = 0; + float* gOutBuf = gHvOutputBuffers; + + // block below copy/pasted from libpd + for (j = 0, p0 = gOutBuf; j < gLibpdBlockSize; ++j, ++p0) { + for (k = 0, p1 = p0 + gLibpdBlockSize * gFirstScopeChannel; k < gScopeChannelsInUse; k++, p1 += gLibpdBlockSize) { + gScopeOut[k] = *p1; + } + scope.log(gScopeOut[0], gScopeOut[1], gScopeOut[2], gScopeOut[3]); + } + } // Interleave the output data if(gHvOutputBuffers != NULL) { @@ -354,5 +429,5 @@ free(gHvInputBuffers); if(gHvOutputBuffers != NULL) free(gHvOutputBuffers); - + delete[] gScopeOut; }