Mercurial > hg > beaglert
comparison examples/basic_libpd/render.cpp @ 342:860c42b3830e prerelease
Updated basic_libpd, now slightly more efficient with less memory operations. Requires the API change in libpd operated in libpd:99a2be8
author | Giulio Moro <giuliomoro@yahoo.it> |
---|---|
date | Mon, 06 Jun 2016 12:21:38 +0100 |
parents | 7af9c5be3434 |
children | 4823ee13bcac |
comparison
equal
deleted
inserted
replaced
341:7af9c5be3434 | 342:860c42b3830e |
---|---|
11 #include <I2c_Codec.h> | 11 #include <I2c_Codec.h> |
12 #include <PRU.h> | 12 #include <PRU.h> |
13 #include <stdio.h> | 13 #include <stdio.h> |
14 #include "z_libpd.h" | 14 #include "z_libpd.h" |
15 #include "z_queued.h" | 15 #include "z_queued.h" |
16 #include "s_stuff.h" | |
16 #include <UdpServer.h> | 17 #include <UdpServer.h> |
17 #include <Midi.h> | 18 #include <Midi.h> |
18 | 19 |
19 | 20 |
20 // setup() is called once before the audio rendering starts. | 21 // setup() is called once before the audio rendering starts. |
39 | 40 |
40 void Bela_printHook(const char *recv){ | 41 void Bela_printHook(const char *recv){ |
41 rt_printf("%s", recv); | 42 rt_printf("%s", recv); |
42 } | 43 } |
43 | 44 |
44 UdpServer udpServer; | |
45 | |
46 void libpdReadFilesLoop(){ | 45 void libpdReadFilesLoop(){ |
47 while(!gShouldStop){ | 46 while(!gShouldStop){ |
48 // check for modified sockets/file descriptors | 47 // check for modified sockets/file descriptors |
49 // (libpd would normally do this every block WITHIN the audio thread) | 48 // (libpd would normally do this every block WITHIN the audio thread) |
50 // not sure if this is thread-safe at the moment | 49 // not sure if this is thread-safe at the moment |
56 #define PARSE_MIDI | 55 #define PARSE_MIDI |
57 AuxiliaryTask libpdReadFilesTask; | 56 AuxiliaryTask libpdReadFilesTask; |
58 AuxiliaryTask libpdProcessMessageQueueTask; | 57 AuxiliaryTask libpdProcessMessageQueueTask; |
59 AuxiliaryTask libpdProcessMidiQueueTask; | 58 AuxiliaryTask libpdProcessMidiQueueTask; |
60 Midi midi; | 59 Midi midi; |
60 //UdpServer udpServer; | |
61 | 61 |
62 bool setup(BelaContext *context, void *userData) | 62 bool setup(BelaContext *context, void *userData) |
63 { | 63 { |
64 midi.readFrom(0); | 64 midi.readFrom(0); |
65 midi.writeTo(0); | 65 midi.writeTo(0); |
67 midi.enableParser(true); | 67 midi.enableParser(true); |
68 #else | 68 #else |
69 midi.enableParser(false); | 69 midi.enableParser(false); |
70 #endif /* PARSE_MIDI */ | 70 #endif /* PARSE_MIDI */ |
71 gChannelsInUse = min((int)(context->analogChannels+context->audioChannels), (int)gChannelsInUse); | 71 gChannelsInUse = min((int)(context->analogChannels+context->audioChannels), (int)gChannelsInUse); |
72 udpServer.bindToPort(1234); | 72 // udpServer.bindToPort(1234); |
73 | 73 |
74 gLibpdBlockSize = libpd_blocksize(); | 74 gLibpdBlockSize = libpd_blocksize(); |
75 // check that we are not running with a blocksize smaller than gLibPdBlockSize | 75 // check that we are not running with a blocksize smaller than gLibPdBlockSize |
76 // it would still work, but the load would be executed unevenly between calls to render | 76 // it would still work, but the load would be executed unevenly between calls to render |
77 if(context->audioFrames < gLibpdBlockSize){ | 77 if(context->audioFrames < gLibpdBlockSize){ |
89 libpd_start_message(1); // one entry in list | 89 libpd_start_message(1); // one entry in list |
90 libpd_add_float(1.0f); | 90 libpd_add_float(1.0f); |
91 libpd_finish_message("pd", "dsp"); | 91 libpd_finish_message("pd", "dsp"); |
92 | 92 |
93 gBufLength = max(gLibpdBlockSize, context->audioFrames); | 93 gBufLength = max(gLibpdBlockSize, context->audioFrames); |
94 unsigned int bufferSize = sizeof(float)*gChannelsInUse*gBufLength; | |
95 gInBuf = (float*)malloc(bufferSize); | |
96 gOutBuf = (float*)malloc(bufferSize); | |
97 // no need to memset to zero | |
98 | 94 |
99 char file[] = "_main.pd"; | 95 char file[] = "_main.pd"; |
100 char folder[] = "./"; | 96 char folder[] = "./"; |
101 // open patch [; pd open file folder( | 97 // open patch [; pd open file folder( |
102 libpd_openfile(file, folder); | 98 libpd_openfile(file, folder); |
103 | 99 gInBuf = libpd_get_sys_soundin(); |
100 gOutBuf = libpd_get_sys_soundout(); | |
104 libpdReadFilesTask = Bela_createAuxiliaryTask(libpdReadFilesLoop, 60, "libpdReadFiles"); | 101 libpdReadFilesTask = Bela_createAuxiliaryTask(libpdReadFilesLoop, 60, "libpdReadFiles"); |
105 Bela_scheduleAuxiliaryTask(libpdReadFilesTask); | 102 Bela_scheduleAuxiliaryTask(libpdReadFilesTask); |
106 | 103 |
107 // Higher priority for the midi queue and lower priority for the message queue. Adjust to taste | 104 // Higher priority for the midi queue and lower priority for the message queue. Adjust to taste |
108 libpdProcessMidiQueueTask = Bela_createAuxiliaryTask(libpd_queued_receive_midi_messages, 80, "libpdProcessMidiQueue"); | 105 libpdProcessMidiQueueTask = Bela_createAuxiliaryTask(libpd_queued_receive_midi_messages, 80, "libpdProcessMidiQueue"); |
193 while((input = midi.getInput()) >= 0){ | 190 while((input = midi.getInput()) >= 0){ |
194 libpd_midibyte(0, input); | 191 libpd_midibyte(0, input); |
195 } | 192 } |
196 #endif /* PARSE_MIDI */ | 193 #endif /* PARSE_MIDI */ |
197 | 194 |
198 unsigned int inW = 0; | |
199 unsigned int outR = 0; | |
200 /* | 195 /* |
201 * NOTE: if you are only using audio (or only analogs) and you are using interleaved buffers | 196 * NOTE: if you are only using audio (or only analogs) and you are using interleaved buffers |
202 * and the blocksize of Bela is the same as gLibPdBlockSize, then you probably | 197 * and the blocksize of Bela is the same as gLibPdBlockSize, then you probably |
203 * do not need the for loops before and after libpd_process_float, so you can save quite some | 198 * do not need the for loops before and after libpd_process_float, so you can save quite some |
204 * memory operations. | 199 * memory operations. |
205 */ | 200 */ |
206 static unsigned int analogChannelsInUse = min(context->analogChannels, gChannelsInUse - context->audioChannels); | 201 static unsigned int analogChannelsInUse = min(context->analogChannels, gChannelsInUse - context->audioChannels); |
207 static unsigned int numberOfPdBlocksToProcess = gBufLength / gLibpdBlockSize; | 202 static unsigned int numberOfPdBlocksToProcess = gBufLength / gLibpdBlockSize; |
208 // rt_printf("channelsInUse: %d, analogChannels in Use: %d\n", gChannelsInUse, analogChannelsInUse); | |
209 for(unsigned int j = 0; j < numberOfPdBlocksToProcess; ++j){ | 203 for(unsigned int j = 0; j < numberOfPdBlocksToProcess; ++j){ |
210 int oldInW = inW; | 204 unsigned int inW = 0; |
205 unsigned int outR = 0; | |
206 | |
211 for(unsigned int n = 0; n < gLibpdBlockSize; ++n){ //pd buffers are interleaved | 207 for(unsigned int n = 0; n < gLibpdBlockSize; ++n){ //pd buffers are interleaved |
212 for(unsigned int ch = 0; ch < context->audioChannels; ++ch){ //first two channels are audio | 208 for(unsigned int ch = 0; ch < context->audioChannels; ++ch){ //first two channels are audio |
213 gInBuf[inW++] = audioRead(context, n, ch); | 209 gInBuf[inW++] = audioRead(context, n, ch); |
214 } | 210 } |
215 // then analogs | 211 // then analogs |
226 for(unsigned int analogCh = 0; analogCh < analogChannelsInUse; ++analogCh){ | 222 for(unsigned int analogCh = 0; analogCh < analogChannelsInUse; ++analogCh){ |
227 gInBuf[inW++] = analogRead(context, n*2, analogCh); | 223 gInBuf[inW++] = analogRead(context, n*2, analogCh); |
228 } | 224 } |
229 } | 225 } |
230 } | 226 } |
231 // TODO: see if we can rewrite libpd_process_float so that it takes a buffer | 227 libpd_process_sys(); // process the block |
232 // of interleaved channels of arbitrary length rather than a series of | |
233 // stacked buffers of size gLibPdBlockSize as it currently does. | |
234 // This would allow to use the buffers as they are rather than having to copy them | |
235 libpd_process_float(1, &gInBuf[oldInW], &gOutBuf[oldInW]); | |
236 for(unsigned int n = 0; n < gLibpdBlockSize; ++n){ //pd buffers are interleaved | 228 for(unsigned int n = 0; n < gLibpdBlockSize; ++n){ //pd buffers are interleaved |
237 unsigned int outAudioFrame = n + j * gLibpdBlockSize; | 229 unsigned int outAudioFrame = 0; |
238 for(unsigned int ch = 0; ch < context->audioChannels; ++ch){ | 230 for(unsigned int ch = 0; ch < context->audioChannels; ++ch){ |
239 audioWrite(context, outAudioFrame, ch, gOutBuf[outR++]); | 231 audioWrite(context, outAudioFrame, ch, gOutBuf[outR++]); |
240 } | 232 } |
241 //and analogs | 233 //and analogs |
242 if(context->analogChannels == 8){ | 234 if(context->analogChannels == 8){ |
270 // Release any resources that were allocated in setup(). | 262 // Release any resources that were allocated in setup(). |
271 | 263 |
272 void cleanup(BelaContext *context, void *userData) | 264 void cleanup(BelaContext *context, void *userData) |
273 { | 265 { |
274 libpd_queued_release(); | 266 libpd_queued_release(); |
275 free(gInBuf); | 267 // free(gInBuf); |
276 free(gOutBuf); | 268 // free(gOutBuf); |
277 } | 269 } |