comparison examples/basic_libpd/render.cpp @ 353:bec5d43e4e7a prerelease

Digital channels are fully managed by Pd
author Giulio Moro <giuliomoro@yahoo.it>
date Wed, 08 Jun 2016 19:44:21 +0100
parents 749aa016fa16
children 1b23300f3e78
comparison
equal deleted inserted replaced
352:749aa016fa16 353:bec5d43e4e7a
4 * Created on: Oct 24, 2014 4 * Created on: Oct 24, 2014
5 * Author: parallels 5 * Author: parallels
6 */ 6 */
7 7
8 #include <Bela.h> 8 #include <Bela.h>
9 #include <DigitalToMessage.h> 9 #include <DigitalChannelManager.h>
10 #include <cmath> 10 #include <cmath>
11 #include <Utilities.h> 11 #include <Utilities.h>
12 #include <I2c_Codec.h> 12 #include <I2c_Codec.h>
13 #include <PRU.h> 13 #include <PRU.h>
14 #include <stdio.h> 14 #include <stdio.h>
43 usleep(1000); 43 usleep(1000);
44 } 44 }
45 } 45 }
46 46
47 #define PARSE_MIDI 47 #define PARSE_MIDI
48 AuxiliaryTask libpdReadFilesTask; 48 static AuxiliaryTask libpdReadFilesTask;
49 Midi midi; 49 static Midi midi;
50 static DigitalChannelManager dcm;
50 //UdpServer udpServer; 51 //UdpServer udpServer;
51 52
52 static uint32_t clearDataOut;
53 static uint32_t setDataOut;
54 static uint16_t digitalModeClear;
55 static uint16_t digitalModeSet;
56 static uint16_t digitalRates;
57 53
58 54
59 void sendDigitalMessage(bool state, unsigned int delay, void* receiverName){ 55 void sendDigitalMessage(bool state, unsigned int delay, void* receiverName){
60 libpd_float((char*)receiverName, (float)state); 56 libpd_float((char*)receiverName, (float)state);
61 // rt_printf("%s: %d\n", (char*)receiverName, state); 57 // rt_printf("%s: %d\n", (char*)receiverName, state);
66 void Bela_messageHook(const char *source, const char *symbol, int argc, t_atom *argv){ 62 void Bela_messageHook(const char *source, const char *symbol, int argc, t_atom *argv){
67 if(strcmp(source, "bela_setDigital") == 0){ 63 if(strcmp(source, "bela_setDigital") == 0){
68 // symbol is the direction, argv[0] is the channel, argv[1] (optional) 64 // symbol is the direction, argv[0] is the channel, argv[1] (optional)
69 // is signal(\"sig\" or \"~\") or message(\"mess\", default) rate 65 // is signal(\"sig\" or \"~\") or message(\"mess\", default) rate
70 bool error = false; 66 bool error = false;
71 bool signal = false; // defaults to message rate 67 bool isMessageRate = true; // defaults to message rate
72 bool direction; 68 bool direction;
73 if(strcmp(symbol, "in") == 0){ 69 if(strcmp(symbol, "in") == 0){
74 direction = INPUT; 70 direction = INPUT;
75 } else if(strcmp(symbol, "out") == 0){ 71 } else if(strcmp(symbol, "out") == 0){
76 direction = OUTPUT; 72 direction = OUTPUT;
90 if(argc >= 2){ 86 if(argc >= 2){
91 t_atom* a = &argv[1]; 87 t_atom* a = &argv[1];
92 if(libpd_is_symbol(a)){ 88 if(libpd_is_symbol(a)){
93 char *s = libpd_get_symbol(a); 89 char *s = libpd_get_symbol(a);
94 if(strcmp(s, "~") == 0 || strncmp(s, "sig", 3) == 0){ 90 if(strcmp(s, "~") == 0 || strncmp(s, "sig", 3) == 0){
95 signal = true; 91 isMessageRate = false;
96 } 92 }
97 } 93 }
98 } 94 }
99 digitalRates = changeBit(digitalRates, channel, signal); 95 dcm.setPinMode(channel, direction, isMessageRate);
100 if(direction == 1){
101 digitalModeClear = setBit(digitalModeClear, channel);
102 digitalModeSet = clearBit(digitalModeSet, channel);
103 } else {
104 digitalModeSet = setBit(digitalModeSet, channel);
105 digitalModeClear = clearBit(digitalModeClear, channel);
106 }
107 // rt_printf("Channel: %d, input?: %d, ~?: %d\n", channel, direction==INPUT, signal);
108 // rt_printf("modeSet 0x%x modeClear 0x%x\n", digitalModeSet, digitalModeClear);
109 } 96 }
110 } 97 }
111 98
112 void Bela_floatHook(const char *source, float value){ 99 void Bela_floatHook(const char *source, float value){
113 // rt_printf("received: %s %f\n", source, value); 100 // rt_printf("received: %s %f\n", source, value);
122 receiver += (source[prefixLength+1] - 48); 109 receiver += (source[prefixLength+1] - 48);
123 // rt_printf("received on digital %d value %.0f\n", receiver, value); 110 // rt_printf("received on digital %d value %.0f\n", receiver, value);
124 unsigned int channel = receiver - 11; // go back to the actual Bela digital channel number 111 unsigned int channel = receiver - 11; // go back to the actual Bela digital channel number
125 if(channel >= 0 && channel < 16){ //16 is the hardcoded value for the number of digital channels 112 if(channel >= 0 && channel < 16){ //16 is the hardcoded value for the number of digital channels
126 //TODO: here we should check if this channel has been registered as message-rate output 113 //TODO: here we should check if this channel has been registered as message-rate output
127 if(value == 0){ 114 dcm.setOutput(channel, value);
128 clearDataOut = setBit(clearDataOut, channel);
129 setDataOut = clearBit(setDataOut, channel);
130 } else {
131 setDataOut = setBit(setDataOut, channel);
132 clearDataOut = clearBit(clearDataOut, channel);
133 }
134 // rt_printf("clear 0x%x set 0x%x\n", clearDataOut, setDataOut); 115 // rt_printf("clear 0x%x set 0x%x\n", clearDataOut, setDataOut);
135 } 116 }
136 } 117 }
137 } 118 }
138 } 119 }
143 {"bela_digitalIn16"},{"bela_digitalIn17"},{"bela_digitalIn18"},{"bela_digitalIn19"},{"bela_digitalIn20"}, 124 {"bela_digitalIn16"},{"bela_digitalIn17"},{"bela_digitalIn18"},{"bela_digitalIn19"},{"bela_digitalIn20"},
144 {"bela_digitalIn21"},{"bela_digitalIn22"},{"bela_digitalIn23"},{"bela_digitalIn24"},{"bela_digitalIn25"}, 125 {"bela_digitalIn21"},{"bela_digitalIn22"},{"bela_digitalIn23"},{"bela_digitalIn24"},{"bela_digitalIn25"},
145 {"bela_digitalIn26"} 126 {"bela_digitalIn26"}
146 }; 127 };
147 128
148 static DigitalToMessage** dtm;
149 static unsigned int analogChannelsInUse; 129 static unsigned int analogChannelsInUse;
150 static unsigned int gLibpdBlockSize; 130 static unsigned int gLibpdBlockSize;
151 static unsigned int gChannelsInUse = 26; 131 static unsigned int gChannelsInUse = 26;
152 132
153 bool setup(BelaContext *context, void *userData) 133 bool setup(BelaContext *context, void *userData)
154 { 134 {
135 dcm.setCallback(sendDigitalMessage);
155 analogChannelsInUse = min(context->analogChannels, gChannelsInUse - context->audioChannels - context->digitalChannels); 136 analogChannelsInUse = min(context->analogChannels, gChannelsInUse - context->audioChannels - context->digitalChannels);
156 dtm = new DigitalToMessage* [context->digitalChannels];
157 if(context->digitalChannels > 0){ 137 if(context->digitalChannels > 0){
158 for(unsigned int ch = 0; ch < context->digitalChannels; ++ch){ 138 for(unsigned int ch = 0; ch < context->digitalChannels; ++ch){
159 dtm[ch] = new DigitalToMessage; 139 dcm.setCallbackArgument(ch, receiverNames[ch]);
160 dtm[ch]->setCallback(sendDigitalMessage, receiverNames[ch]);
161 if((ch%2) == 0 )
162 pinMode(context, 0, ch, INPUT);
163 else
164 pinMode(context, 0, ch, OUTPUT);
165 } 140 }
166 } 141 }
167 midi.readFrom(0); 142 midi.readFrom(0);
168 midi.writeTo(0); 143 midi.writeTo(0);
169 #ifdef PARSE_MIDI 144 #ifdef PARSE_MIDI
197 libpd_add_float(1.0f); 172 libpd_add_float(1.0f);
198 libpd_finish_message("pd", "dsp"); 173 libpd_finish_message("pd", "dsp");
199 174
200 gBufLength = max(gLibpdBlockSize, context->audioFrames); 175 gBufLength = max(gLibpdBlockSize, context->audioFrames);
201 176
202 char file[] = "_main.pd";
203 char folder[] = "./";
204 // open patch [; pd open file folder(
205 libpd_openfile(file, folder);
206 177
207 // bind your receivers here 178 // bind your receivers here
208 libpd_bind("bela_digitalOut11"); 179 libpd_bind("bela_digitalOut11");
209 libpd_bind("bela_digitalOut12"); 180 libpd_bind("bela_digitalOut12");
210 libpd_bind("bela_digitalOut13"); 181 libpd_bind("bela_digitalOut13");
221 libpd_bind("bela_digitalOut24"); 192 libpd_bind("bela_digitalOut24");
222 libpd_bind("bela_digitalOut25"); 193 libpd_bind("bela_digitalOut25");
223 libpd_bind("bela_digitalOut26"); 194 libpd_bind("bela_digitalOut26");
224 libpd_bind("bela_setDigital"); 195 libpd_bind("bela_setDigital");
225 196
197 char file[] = "_main.pd";
198 char folder[] = "./";
199 // open patch [; pd open file folder(
200 libpd_openfile(file, folder);
226 libpdReadFilesTask = Bela_createAuxiliaryTask(libpdReadFilesLoop, 60, "libpdReadFiles"); 201 libpdReadFilesTask = Bela_createAuxiliaryTask(libpdReadFilesLoop, 60, "libpdReadFiles");
227 Bela_scheduleAuxiliaryTask(libpdReadFilesTask); 202 Bela_scheduleAuxiliaryTask(libpdReadFilesTask);
228 203
229 204
230 return true; 205 return true;
357 } 332 }
358 } 333 }
359 } 334 }
360 335
361 //then digital 336 //then digital
362 //TODO: in multiple places below we assume that the number of digitals is same as number of audio 337 // note: in multiple places below we assume that the number of digitals is same as number of audio
363 // digital in at message-rate 338 // digital in at message-rate
364 for(unsigned int n = 0; n < context->digitalChannels; ++n){ 339 dcm.processInput(&context->digital[audioFrameBase], gLibpdBlockSize);
365 // note that we consider only the first sample of the block 340
366 // considering all of them is notably more expensive
367 // TODO: only process the channels marked as such
368 dtm[n]->process(n + 16, &context->digital[audioFrameBase], 1);
369 }
370 // digital in at signal-rate 341 // digital in at signal-rate
371 for (j = 0, p0 = gInBuf; j < gLibpdBlockSize; j++, p0++) { 342 for (j = 0, p0 = gInBuf; j < gLibpdBlockSize; j++, p0++) {
343 unsigned int digitalFrame = audioFrameBase + j;
372 for (k = 0, p1 = p0 + gLibpdBlockSize * (context->audioChannels + 8); 344 for (k = 0, p1 = p0 + gLibpdBlockSize * (context->audioChannels + 8);
373 k < 16; ++k, p1 += gLibpdBlockSize) { 345 k < 16; ++k, p1 += gLibpdBlockSize) {
374 // note that we only write the last sample of the block 346 if(dcm.isSignalRate(k) && dcm.isInput(k)){ // only process input channels that are handled at signal rate
375 // writing all of them is notably more expensive. 347 *p1 = digitalRead(context, digitalFrame, k);
376 348 }
377 // TODO: only process the channels marked as such
378 unsigned int digitalFrame = audioFrameBase + j;
379 *p1 = digitalRead(context, digitalFrame, k);
380 } 349 }
381 } 350 }
382 351
383 libpd_process_sys(); // process the block 352 libpd_process_sys(); // process the block
384 353
385 //digital out 354 //digital out
386 // digital out at signal-rate 355 // digital out at signal-rate
387 for (j = 0, p0 = gOutBuf; j < gLibpdBlockSize; ++j, ++p0) { 356 for (j = 0, p0 = gOutBuf; j < gLibpdBlockSize; ++j, ++p0) {
388 unsigned int digitalFrame = (audioFrameBase + j); 357 unsigned int digitalFrame = (audioFrameBase + j);
389 for (k = 0, p1 = p0 + gLibpdBlockSize * (context->audioChannels + 8); 358 for (k = 0, p1 = p0 + gLibpdBlockSize * (context->audioChannels + 8);
390 k < context->digitalChannels; k++, p1 += gLibpdBlockSize) { 359 k < context->digitalChannels; k++, p1 += gLibpdBlockSize) {
391 // TODO: only process the channels marked as such 360 if(dcm.isSignalRate(k) && dcm.isOutput(k)){ // only process output channels that are handled at signal rate
392 digitalWriteOnce(context, digitalFrame, k, *p1 > 0.5); 361 digitalWriteOnce(context, digitalFrame, k, *p1 > 0.5);
362 }
393 } 363 }
394 } 364 }
395 365
396 // digital out at message-rate 366 // digital out at message-rate
397 if(clearDataOut || setDataOut || digitalModeSet || digitalModeClear){ 367 dcm.processOutput(&context->digital[audioFrameBase], gLibpdBlockSize);
398 uint32_t orWord = ((setDataOut << 16) | digitalModeSet);
399 uint32_t andTildeWord = ((clearDataOut << 16) | digitalModeClear);
400 uint32_t outWord;
401 for (unsigned int frame = audioFrameBase; frame < audioFrameBase + gLibpdBlockSize; ++frame) {
402 outWord = context->digital[frame];
403 outWord = outWord | orWord;
404 outWord = outWord &~ andTildeWord;
405 context->digital[frame] = outWord;
406 }
407 }
408 368
409 //audio 369 //audio
410 for (j = 0, p0 = gOutBuf; j < gLibpdBlockSize; j++, p0++) { 370 for (j = 0, p0 = gOutBuf; j < gLibpdBlockSize; j++, p0++) {
411 for (k = 0, p1 = p0; k < context->audioChannels; k++, p1 += gLibpdBlockSize) { 371 for (k = 0, p1 = p0; k < context->audioChannels; k++, p1 += gLibpdBlockSize) {
412 audioWrite(context, audioFrameBase + j, k, *p1); 372 audioWrite(context, audioFrameBase + j, k, *p1);
442 // cleanup() is called once at the end, after the audio has stopped. 402 // cleanup() is called once at the end, after the audio has stopped.
443 // Release any resources that were allocated in setup(). 403 // Release any resources that were allocated in setup().
444 404
445 void cleanup(BelaContext *context, void *userData) 405 void cleanup(BelaContext *context, void *userData)
446 { 406 {
447 delete[] dtm; 407 }
448 }