@@ -31,12 +31,13 @@ using namespace LfpDisplayNodeBeta;
3131LfpDisplayNode::LfpDisplayNode ()
3232 : GenericProcessor (" LFP Viewer Beta" )
3333 , displayGain (1 )
34- , bufferLength (20 .0f )
34+ , bufferLength (20 .0f ) // seconds
3535 , abstractFifo (100 )
3636{
3737 setProcessorType (PROCESSOR_TYPE_SINK);
3838
39- displayBuffer = new AudioSampleBuffer (8 , 100 );
39+ displayBuffer = new AudioSampleBuffer (8 , 100 ); // channels, samples
40+ // (Size is later changed by resizeBuffer() to [bufferLength = 20] seconds.)
4041
4142 const int heapSize = 5000 ;
4243 arrayOfOnes = new float [heapSize];
@@ -68,15 +69,15 @@ void LfpDisplayNode::updateSettings()
6869 eventSourceNodes.clear ();
6970 ttlState.clear ();
7071
71- for (int i = 0 ; i < eventChannelArray.size (); ++i)
72- {
73- uint32 sourceID = getChannelSourceID (eventChannelArray[i]);
74- if (!eventSourceNodes.contains (sourceID))
75- {
76- eventSourceNodes.add (sourceID);
72+ for (int i = 0 ; i < eventChannelArray.size (); ++i)
73+ {
74+ uint32 sourceID = getChannelSourceID (eventChannelArray[i]);
75+ if (!eventSourceNodes.contains (sourceID))
76+ {
77+ eventSourceNodes.add (sourceID);
7778
78- }
79- }
79+ }
80+ }
8081
8182 numEventChannels = eventSourceNodes.size ();
8283
@@ -96,7 +97,7 @@ void LfpDisplayNode::updateSettings()
9697
9798uint32 LfpDisplayNode::getChannelSourceID (const EventChannel* event) const
9899{
99- return getProcessorFullId (event->getTimestampOriginProcessor (), event->getTimestampOriginSubProcessor ());
100+ return getProcessorFullId (event->getTimestampOriginProcessor (), event->getTimestampOriginSubProcessor ());
100101}
101102
102103bool LfpDisplayNode::resizeBuffer ()
@@ -110,6 +111,9 @@ bool LfpDisplayNode::resizeBuffer()
110111 {
111112 abstractFifo.setTotalSize (nSamples);
112113 displayBuffer->setSize (nInputs + numEventChannels, nSamples); // add extra channels for TTLs
114+ displayBuffer->clear ();
115+ // displayBufferIndex.clear();
116+ // displayBufferIndex.insertMultiple(0, 0, nInputs + numEventChannels);
113117
114118 return true ;
115119 }
@@ -139,6 +143,7 @@ bool LfpDisplayNode::disable()
139143{
140144 LfpDisplayEditor* editor = (LfpDisplayEditor*) getEditor ();
141145 editor->disable ();
146+ eventValueChanges.clear ();
142147 return true ;
143148}
144149
@@ -157,170 +162,103 @@ void LfpDisplayNode::setParameter (int parameterIndex, float newValue)
157162 ed->canvas ->setParameter (parameterIndex, newValue);
158163}
159164
160-
161- void LfpDisplayNode::handleEvent (const EventChannel* eventInfo, const MidiMessage& event, int samplePosition)
162- {
163- if (Event::getEventType (event) == EventChannel::TTL)
164- {
165- TTLEventPtr ttl = TTLEvent::deserializeFromMessage (event, eventInfo);
166-
167- // int eventNodeId = *(dataptr+1);
168- const int eventId = ttl->getState () ? 1 : 0 ;
169- const int eventChannel = ttl->getChannel ();
170- const int eventTime = samplePosition;
171- const uint32 eventSourceNodeId = getChannelSourceID (eventInfo);
172- const int nSamples = getNumSourceSamples (eventSourceNodeId);
173- int samplesToFill = nSamples - eventTime;
174- if (samplesToFill < 0 ) samplesToFill = 0 ;
175-
176- // std::cout << "Received event from " << eventSourceNode << ", channel "
177- // << eventChannel << ", with ID " << eventId << ", copying to "
178- // << channelForEventSource[eventSourceNode] << std::endl;
179- // //
180- int bufferIndex = (displayBufferIndex[channelForEventSource[eventSourceNodeId]] + eventTime - nSamples)
181- % displayBuffer->getNumSamples ();
182-
183- bufferIndex = bufferIndex >= 0
184- ? bufferIndex
185- : displayBuffer->getNumSamples () + bufferIndex;
186-
187- if (eventId == 1 )
188- {
189- ttlState[eventSourceNodeId] |= (1L << eventChannel);
190- }
191- else
192- {
193- ttlState[eventSourceNodeId] &= ~(1L << eventChannel);
194- }
195-
196- if (samplesToFill + bufferIndex < displayBuffer->getNumSamples ())
197- {
198- // std::cout << bufferIndex << " " << samplesToFill << " " << ttlState[eventSourceNode] << std::endl;
199-
200- displayBuffer->copyFrom (channelForEventSource[eventSourceNodeId], // destChannel
201- bufferIndex, // destStartSample
202- arrayOfOnes, // source
203- samplesToFill, // numSamples
204- float (ttlState[eventSourceNodeId])); // gain
205- }
206- else
207- {
208- const int block2Size = (samplesToFill + bufferIndex) % displayBuffer->getNumSamples ();
209- const int block1Size = samplesToFill - block2Size;
210-
211- displayBuffer->copyFrom (channelForEventSource[eventSourceNodeId], // destChannel
212- bufferIndex, // destStartSample
213- arrayOfOnes, // source
214- block1Size, // numSamples
215- float (ttlState[eventSourceNodeId])); // gain
216-
217- displayBuffer->copyFrom (channelForEventSource[eventSourceNodeId], // destChannel
218- 0 , // destStartSample
219- arrayOfOnes, // source
220- block2Size, // numSamples
221- float (ttlState[eventSourceNodeId])); // gain
222- }
223-
224- // std::cout << "Received event from " << eventNodeId
225- // << " on channel " << eventChannel
226- // << " with value " << eventId
227- // << " at timestamp " << event.getTimeStamp() << std::endl;
228- }
165+ std::list<int > LfpDisplayNode::eventStateChannels () const {
166+ std::list<int > cc;
167+ for (uint32 id: eventSourceNodes)
168+ cc.push_back (channelForEventSource.find (id)->second );
169+ return cc;
170+ }
171+
172+ void LfpDisplayNode::handleEvent (const EventChannel* eventInfo,
173+ const MidiMessage& event, int samplePosition) {
174+ if (Event::getEventType (event) == EventChannel::TTL) {
175+ TTLEventPtr ttl = TTLEvent::deserializeFromMessage (event, eventInfo);
176+ const int eventChannel = ttl->getChannel ();
177+ const int eventTime = samplePosition;
178+ const uint32 eventSourceNodeId = getChannelSourceID (eventInfo);
179+ int val = 1 <<eventChannel;
180+ if (!ttl->getState ())
181+ val = -val;
182+ eventValueChanges[eventSourceNodeId].push_back (EventValueChange (eventTime, val));
183+ }
229184}
230185
186+ void LfpDisplayNode::initializeEventChannels () {
187+ for (int i=0 ; i<eventSourceNodes.size (); i++) {
188+ uint32 src = eventSourceNodes[i];
189+ eventValueChanges[src] = std::list<EventValueChange>();
190+ }
191+ }
231192
232- void LfpDisplayNode::initializeEventChannels ()
233- {
234- for (int i = 0 ; i < eventSourceNodes.size (); ++i)
235- {
236- const int chan = channelForEventSource[eventSourceNodes[i]];
237- const int index = displayBufferIndex[chan];
238- const int samplesLeft = displayBuffer->getNumSamples () - index;
239- const int nSamples = getNumSourceSamples (eventSourceNodes[i]);
240-
241- // std::cout << "Event source node " << i << ", channel " << chan << std::endl;
242-
243- if (nSamples < samplesLeft)
244- {
245- // std::cout << getNumInputs()+1 << " " << displayBufferIndex << " " << totalSamples << " " << ttlState << std::endl;
246-
247- displayBuffer->copyFrom (chan, // destChannel
248- index, // destStartSample
249- arrayOfOnes, // source
250- nSamples, // numSamples
251- float (ttlState[eventSourceNodes[i]])); // gain
252-
253- displayBufferIndex.set (chan, index + nSamples);
254- }
255- else
256- {
257- int extraSamples = nSamples - samplesLeft;
258-
259- displayBuffer->copyFrom (chan, // destChannel
260- index, // destStartSample
261- arrayOfOnes, // source
262- samplesLeft, // numSamples
263- float (ttlState[eventSourceNodes[i]])); // gain
264-
265- displayBuffer->copyFrom (chan, // destChannel
266- 0 , // destStartSample
267- arrayOfOnes, // source
268- extraSamples, // numSamples
269- float (ttlState[eventSourceNodes[i]])); // gain
193+ void LfpDisplayNode::copyToEventChannel (uint32 src,
194+ int t0,
195+ int t1,
196+ float value) {
197+ int dispBufSamps = displayBuffer->getNumSamples ();
198+ int chan = channelForEventSource[src];
199+ int destStart = t0 + displayBufferIndex[chan];
200+ int n = t1 - t0;
201+ while (destStart + n >= dispBufSamps) {
202+ int m = dispBufSamps - destStart;
203+ displayBuffer->copyFrom (chan, destStart, arrayOfOnes, m, value);
204+ n -= m;
205+ destStart = 0 ;
206+ }
207+ if (n>0 )
208+ displayBuffer->copyFrom (chan, destStart, arrayOfOnes, n, value);
209+ }
270210
271- displayBufferIndex.set (chan, extraSamples);
272- }
211+ void LfpDisplayNode::finalizeEventChannels () {
212+ for (int i=0 ; i<eventSourceNodes.size (); ++i) {
213+ uint32 src = eventSourceNodes[i];
214+ int chan = channelForEventSource[src];
215+ int index = displayBufferIndex[chan];
216+ int nSamples = getNumSourceSamples (src);
217+ int t0 = 0 ;
218+ for (EventValueChange const &evc: eventValueChanges[src]) {
219+ int t1 = evc.eventTime ;
220+ copyToEventChannel (src, t0, t1, ttlState[src]);
221+ if (evc.eventVal >0 )
222+ ttlState[src] |= evc.eventVal ;
223+ else
224+ ttlState[src] &= ~evc.eventVal ;
225+ t0 = t1;
273226 }
227+ copyToEventChannel (src, t0, nSamples, ttlState[src]);
228+ displayBufferIndex.set (chan, (index + nSamples)
229+ % displayBuffer->getNumSamples ());
230+ }
274231}
275232
233+ void LfpDisplayNode::copyDataToDisplay (int chan, AudioSampleBuffer &srcbuf) {
234+ int n = getNumSamples (chan);
235+ int idx = displayBufferIndex[chan];
236+ int buflen = displayBuffer->getNumSamples ();
237+ int t0 = 0 ;
238+ while (idx + n >= buflen) {
239+ int m = buflen - idx;
240+ displayBuffer->copyFrom (chan, idx, srcbuf, chan, t0, m);
241+ t0 += m;
242+ n -= m;
243+ idx = 0 ;
244+ }
245+ if (n>0 ) {
246+ displayBuffer->copyFrom (chan, idx, srcbuf, chan, t0, n);
247+ idx += n;
248+ }
249+ displayBufferIndex.set (chan, idx);
250+ }
276251
277252void LfpDisplayNode::process (AudioSampleBuffer& buffer)
278253{
279254 // 1. place any new samples into the displayBuffer
280255 // std::cout << "Display node sample count: " << nSamples << std::endl; ///buffer.getNumSamples() << std::endl;
281256
282257 initializeEventChannels ();
283-
284- checkForEvents (); // see if we got any TTL events
285-
286- ScopedLock displayLock (displayMutex);
287-
288- for (int chan = 0 ; chan < buffer.getNumChannels (); ++chan)
289- {
290- const int samplesLeft = displayBuffer->getNumSamples () - displayBufferIndex[chan];
291- const int nSamples = getNumSamples (chan);
292-
293- if (nSamples < samplesLeft)
294- {
295- displayBuffer->copyFrom (chan, // destChannel
296- displayBufferIndex[chan], // destStartSample
297- buffer, // source
298- chan, // source channel
299- 0 , // source start sample
300- nSamples); // numSamples
301-
302- displayBufferIndex.set (chan, displayBufferIndex[chan] + nSamples);
303- }
304- else
305- {
306- const int extraSamples = nSamples - samplesLeft;
307-
308- displayBuffer->copyFrom (chan, // destChannel
309- displayBufferIndex[chan], // destStartSample
310- buffer, // source
311- chan, // source channel
312- 0 , // source start sample
313- samplesLeft); // numSamples
314-
315- displayBuffer->copyFrom (chan, // destChannel
316- 0 , // destStartSample
317- buffer, // source
318- chan, // source channel
319- samplesLeft, // source start sample
320- extraSamples); // numSamples
321-
322- displayBufferIndex.set (chan, extraSamples);
323- }
324- }
258+ checkForEvents (); // see if we got any TTL events
259+ ScopedLock displayLock (displayMutex);
260+ finalizeEventChannels ();
261+ for (int chan = 0 ; chan < buffer.getNumChannels (); ++chan)
262+ copyDataToDisplay (chan, buffer);
325263}
326264
0 commit comments